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

Undefined symbols "vtable for ..." and "typeinfo for..."?

提问人:Lisa 提问时间:11/8/2009 最后编辑:Martin J.Lisa 更新时间:10/23/2023 访问量:61084

问:

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

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++ 链接器错误 undefined-reference vtable pure-virtual

评论

0赞 Troubadour 11/8/2009
记得回到你原来的问题,发布一些代码,或者回答人们在那里问你的一些问题。这可能会让你更快地得到结果。:)
0赞 Lisa 11/8/2009
我真的很想,但网站只是丢失了,谢谢,我会回去的
0赞 Saro Bear 6/13/2014
请在这里找到答案!stackoverflow.com/questions/1458180/......
1赞 heLomaN 1/24/2018
其他人则提到了所发生的事情的真相。但是,尽管有些虚函数没有实现,代码文件没有放到编译器源文件列表中也是:(的可能原因。

答:

2赞 R Samuel Klatchko 11/8/2009 #1

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

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

评论

0赞 Lisa 11/8/2009
就上面的错误而言,未定义的符号是什么意思?
5赞 bk1e 11/8/2009 #2

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

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

评论

0赞 Lisa 11/8/2009
我必须有一个 Obstacle.cc,因为它只有一些虚拟功能吗?
0赞 bk1e 11/8/2009
@Lisa:不一定,但在 .h 文件中定义非内联非模板方法/函数可能会导致不同的链接器错误(多个定义)。因此,我假设 Obstacle 中的所有内容都是内联的。您是否为 Obstacle 的所有成员函数编写了定义,包括构造函数和析构函数?请注意,如果 Obstacle 具有纯虚拟析构函数,您仍然需要为其编写定义。
0赞 outis 11/8/2009
障碍物只有纯虚拟功能吗?打击这一点 - 当涉及到 vtables 时并不重要。您需要一个 Obstacle.o,以便编译器在某个地方存储 Obstacle 的虚拟表并键入 info。
1赞 Mike Seymour 11/8/2009
@outis:不需要,您不需要目标文件。如果所有虚拟成员函数都是内联函数或纯虚拟函数,则编译器必须找到放置 vtable 的位置。这通常是通过在每个对象文件中生成一个“链接一次”部分来完成的。
107赞 Mike Seymour 11/8/2009 #3

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

virtual void Method() = 0;

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

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

评论

0赞 Aishwar 11/8/2009
我只是在自己的代码中遇到了这个问题。我通过谷歌搜索找到了这个页面,我做了你说的更改,它修复了它。谢谢!:D
0赞 Marm0t 11/12/2010
与上面相同 - 在谷歌上找到 - 立即解决了问题,解决方案既快速又简单!我在虚拟函数列表中添加了另一个纯虚拟成员,但忘记添加 = 0 标记!哎呀
1赞 mcmlxxxvi 1/26/2013
注意:抽象类可以具有具有“默认”实现的虚拟方法(驻留在同一个基类中),后续类可能会或可能不会覆盖这些实现。如果要使用这样的虚拟方法,请不要在基类中将它们声明为“纯虚拟”(= 0)。
13赞 janm 11/8/2009 #4

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

virtual ~Obstacle();

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

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

评论

3赞 Ricket 11/16/2011
就我而言,我不仅需要定义析构函数,而且还忘记在我的 cpp 文件中定义实现。
0赞 code4j 1/3/2023
我还需要定义实现以使其工作
12赞 vine'th 10/15/2017 #5

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

评论

1赞 KevinL 10/6/2023
非常感谢你!我有一个错误,例如: 这是由于我编译了一个库,但在编译第二个库时忘记设置它(这取决于第一个库)ld.lld: error: undefined symbol: typeinfo for MySuperClass>>> referenced by SubClass.cpp>>> SubClass.o:(typeinfo for ... in libcore.a)>>> did you mean: vtable for MySuperClass-fno-rtti
1赞 Daniel Walker 10/21/2023 #6

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

如果像我一样,在中间类中实现该方法,甚至可能会发生这种情况。例如

class Base {
public:
    virtual void func() = 0;
};

class Intermediate : public Base {
public:
    void func(); // implemented in source file
};

class Foo : public Intermediate {
    void func(); // not implemented and so a linker error will occur
};