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

Lis*_*isa 46 c++ linker-errors pure-virtual vtable undefined-reference

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

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
Run Code Online (Sandbox Code Playgroud)

vtable和typeinfo的含义是什么?

Mik*_*our 85

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

virtual void Method() = 0;
Run Code Online (Sandbox Code Playgroud)

= 0讲述这个方法必须由一个派生类中重写编译器,可能不会有它自己的实现.

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


jan*_*anm 6

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

virtual ~Obstacle();
Run Code Online (Sandbox Code Playgroud)

析构函数的定义还为具有虚函数的类创建vtable.它还确保通过基类指针删除派生类实例做正确的事情.

(我对问题的回答的副本我应该怎么处理这个奇怪的错误?这似乎是重复的.)

  • 在我的例子中,我不仅需要定义析构函数,还忘记在我的cpp文件中定义实现. (3认同)

bk1*_*k1e 5

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

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


vin*_*'th 5

您可能会收到此错误还有另一个原因,只是想在此处记录下来。我正在链接一个没有 RTTI 的静态库。所以使用-fno-rtti为我修复的 C++ 标志。如果您不需要 RTTI,也可以使用此标志。希望这可以帮助。


R S*_*hko 2

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

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