C++关于vtable的错误
vtable的意思是虚函数表。
原文转自:https://wsong83.wordpress.com/2012/03/27/c关于vtable的奇怪错误/
今天遇到了一个关于C++ vtable的奇怪错误,乍一看还真的很难理解,值得记录一下。
假设下面的程序:
class Father {
public:
virtual void function() const = 0;
};
class Child : public Father {
public:
Child(unsigned int data)
: data(data) {}
void function() const;
//data
private:
int data;
};
int main() {
Child m_child(3);
return 0;
}
看起来这段程序没有任何问题。尽管Child类中的function()没有定义,但是在main()中并不会用到Child::function(),所以一般情况下编译和连接都没有问题。
但是实际情况是:编译会通过,连接时会报出类似如下的错误:
undefined reference to `vtable for Child
感觉上有函数没有定义,可是找不到任何需要定义的函数。这里的错误很可能报在构造函数的位置,使得错误信息更难理解了。信息中的vtable是唯一有用的信息,提示错误和虚函数有关。
为了能正确连接,这段程序中我们必须定义一个function()的函数体。由于function是Father中纯虚函数的一个重载,Child类则默认存在一个虚函数表以存储重载虚函数。但由于function()没有函数定义,编译生成的目标代码没有生成任何有效的虚函数表,因而导致连接时出现找不到vtable的错误。如果function()是一个普通函数则不会出现如上问题。
感觉上,如果一个子类重载了任何虚函数,需要提供至少一个虚函数的实现,否则就会出现如上很难理解的错误。