未定义的符号“vtable for ...”和“typeinfo for...”?

问题描述 投票:0回答:6

几乎是最后一步,但仍然出现一些奇怪的错误......

bash-3.2$ make
g++ -Wall -c -g Myworld.cc
g++ -Wall -g solvePlanningProblem.o Position.o AStarNode.o PRM.o PRMNode.o World.o SingleCircleWorld.o Myworld.o RECTANGLE.o CIRCLE.o -o solvePlanningProblem
Undefined symbols:
  "vtable for Obstacle", referenced from:
      Obstacle::Obstacle()in Myworld.o
  "typeinfo for Obstacle", referenced from:
      typeinfo for RECTANGLEin RECTANGLE.o
      typeinfo for CIRCLEin CIRCLE.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [solvePlanningProblem] Error 1

vtable 和 typeinfo 是什么意思?

c++ linker-errors undefined-reference vtable pure-virtual
6个回答
105
投票

如果 Obstacle 是抽象基类,那么请确保将其所有虚拟方法声明为“纯虚拟”:

virtual void Method() = 0;

= 0
告诉编译器此方法必须由派生类重写,并且可能没有自己的实现。

如果该类包含任何非纯虚函数,那么编译器将假设它们在某处有一个实现,并且其内部结构(vtable 和 typeinfo)可能会在与其中之一相同的目标文件中生成;如果这些功能没有实现,那么内部结构就会丢失,你会得到这些错误。


12
投票

Obstacle 类需要一个虚拟析构函数。将析构函数定义更改为:

virtual ~Obstacle();

析构函数的定义还为具有虚函数的类创建虚函数表。它还确保通过基类指针删除派生类实例是正确的。

(我对问题的答案的副本我应该如何处理这个奇怪的错误?这似乎是重复的。)


11
投票

还有另一个原因会导致您收到此错误,并且只想在此处记录它。我正在链接一个没有 RTTI 的静态库。所以使用 C++ 标志

-fno-rtti
为我解决了。如果不需要 RTTI,也可以使用此标志。希望这有帮助。


4
投票

您有

Obstacle.cc
文件吗?如果是这样,您需要确保它被内置到
Obstacle.o
中,并且当您链接程序时
Obstacle.o
被添加到命令行中。

此外,请确保定义了声明的所有非纯虚拟方法。如果您声明纯虚拟析构函数,您也需要定义它。


2
投票

vtable 和 typeinfo 是 C++ 编译器生成的内部结构。 vtable 用于调用虚拟函数,typeinfo 用于 RTTI。

不同的编译器在生成这些结构时有不同的策略。我见过的一个策略是他们将在包含类中第一个虚函数的同一目标文件中生成表。


0
投票

如果您错误地在子类中声明了该方法但忘记实现它,则可能会出现此错误。

© www.soinside.com 2019 - 2024. All rights reserved.