49

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

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是什么意思?

4

5 回答 5

95

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

virtual void Method() = 0;

告诉编译器这个= 0方法必须被派生类覆盖,并且可能没有自己的实现。

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

于 2009-11-07T17:31:54.653 回答
8

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

virtual ~Obstacle();

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

(我对这个奇怪的错误该怎么办?这似乎是重复的问题的答案的副本。)

于 2009-11-08T00:08:43.910 回答
5

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

于 2017-10-15T06:32:37.660 回答
4

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

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

于 2009-11-07T17:00:39.053 回答
1

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

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

于 2009-11-07T16:51:28.510 回答