缺少类方法时出现奇怪的错误消息

时间:2011-09-25 12:17:41

标签: c++ oop ld

  

可能重复:
  GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'

由于奇怪的ld错误,我长时间一直撞在墙上。 所以我在一个小的测试用例中重现了它以理解这个问题。

我宣布了一个类,我在头文件中派生了另一个:

class BaseClass {
public:
  BaseClass(){};
  virtual void func(){};
};

class DerivedClass: public BaseClass {
public:
  DerivedClass();
  void func();
};

然后我定义了构造函数,但忘了定义func(这里是自愿的,但实际上我用愚蠢的复制/粘贴做了...):

DerivedClass::DerivedClass(){
  cout << "Derived constructor" << endl;
}

//void DerivedClass::func(){
//  cout << "Derived func" << endl;
//}

然后我得到:

  

未定义引用`vtable for DerivedClass'

编辑:该消息指出了构造函数的声明!

如果我取消注释func的定义,那么我没有错误。所以我的问题: 为什么链接器没有告诉我func的定义丢失了?

当你有经验时,解决方案可能很明显,但对于像我这样的初学者来说,它不是!

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

vtable是为包含虚函数的类和从它派生的类创建的。这意味着在您的程序vtable中将为BaseClassDerivedClass创建。这些vtables中的每一个都包含虚函数void func()的地址。现在请注意DerivedClass不包含void func()的定义,因此vtable包含BaseClass的{​​{1}}函数的地址。这就是编译器提供错误void func()的原因。

答案 1 :(得分:0)

您的编译器似乎没有为vtable生成DerivedClassvtable基本上是一个包含每个虚函数的函数指针的表。通过为每个对象存储指向类vtable(通常称为vptr)的指针,可以在运行时确定要调用的正确虚函数。虽然它是特定编译器的实现细节,但这是实现虚拟函数的常用方法,虚函数在运行时绑定,因此不能像普通函数一样调用。

我的第一个猜测是编译器没有为vtable生成DerivedClass因为它没有定义任何虚函数所以它使用BaseClass的{​​{1}} }}。虽然这有点奇怪,但这是我能提出的唯一想法。但我并不精通编译器架构,也许有人有更好的解决方案。

相关问题