提问人:Lisa 提问时间:11/8/2009 最后编辑:Martin J.Lisa 更新时间:10/23/2023 访问量:61087
未定义的符号“vtable for ...”和“typeinfo for...”?
Undefined symbols "vtable for ..." and "typeinfo for..."?
问:
几乎是最后一步,但仍然有一些奇怪的错误......
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 是什么意思?
答:
vtable 和 typeinfo 是由 C++ 编译器生成的内部结构。vtable 用于调用 virtuable 函数,typeinfo 用于 RTTI。
不同的编译器在生成这些结构时有不同的策略。我见过的一种策略是,他们将在包含类中第一个虚拟函数的同一对象文件中生成表。
评论
你有文件吗?如果是这样,您需要确保它内置于 ,并在链接程序时将其添加到命令行中。Obstacle.cc
Obstacle.o
Obstacle.o
此外,请确保定义了您声明的所有非纯虚拟方法。如果声明一个纯虚拟析构函数,则也需要定义它。
评论
如果 Obstacle 是一个抽象基类,请确保将其所有虚拟方法声明为“纯虚拟”:
virtual void Method() = 0;
告诉编译器此方法必须由派生类重写,并且可能没有自己的实现。= 0
如果该类包含任何非纯虚函数,则编译器将假定它们在某处具有实现,并且其内部结构(vtable 和 typeinfo)可能在与其中一个相同的对象文件中生成;如果未实现这些功能,则内部结构将丢失,并且您将收到这些错误。
评论
Obstacle 类需要一个虚拟析构函数。将析构函数定义更改为:
virtual ~Obstacle();
析构函数的定义还为具有虚函数的类创建 vtable。它还确保通过基类指针删除派生类实例执行正确的操作。
(我对问题的回答副本 我应该如何处理这个奇怪的错误?这似乎是重复的。
评论
还有另一个原因,您可能会收到此错误,并且只想在此处记录它。我正在与一个没有 RTTI 的静态库链接。所以使用 C++ 标志为我修复。如果不需要 RTTI,也可以使用此标志。希望这会有所帮助。-fno-rtti
评论
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
如果您错误地在子类中声明了该方法,但忘记实现它,则可能会出现此错误。
如果像我一样,在中间类中实现该方法,甚至可能会发生这种情况。例如
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
};
评论