为何给C++类成员函数添加virtual关键字会引发编译错误?
为什么含虚函数的类未定义虚函数会触发链接错误?
原代码正常编译的情况
以下代码可以正常编译:
class Base{ public: int fcn(); // clause 2 }; int main() { Base b; // clause 1 }
原因很简单:创建Base对象b时,编译器只需要类的声明信息来确定对象的大小和布局,不需要成员函数fcn的具体定义——而且代码里根本没调用fcn,所以链接阶段也不会去寻找它的实现,自然不会报错。
添加virtual后的链接错误
当给fcn加上virtual关键字后,代码变成:
class Base{ public: virtual int fcn(); // clause 2 }; int main() { Base b; // clause 1 }
此时会触发链接错误,错误信息如下:
/usr/bin/ld: /tmp/ccVGJNMU.o: in function `main': main.cpp:(.text+0x1e): undefined reference to `vtable for Base' collect2: error: ld returned 1 exit status
错误原因解析
- C++规定,只要类包含至少一个虚函数,编译器就会为该类生成虚函数表(vtable)。这个表是一块内存区域,存储着类的所有虚函数的地址,用于实现运行时多态。
- 虚函数表的生成必须依赖虚函数的定义:如果只声明虚函数但不提供实现,编译器无法把该函数的地址填入虚函数表,也就无法生成完整的虚函数表。
- 当你实例化
Base对象b时,编译器会在对象中插入一个指向虚函数表的指针(vptr)。链接阶段需要找到对应的虚函数表,但因为虚函数fcn没有定义,编译器无法生成这个表,链接器就会抛出"undefined reference to `vtable for Base'"的错误。 - 额外说明:如果把
fcn声明为纯虚函数(virtual int fcn() = 0;),Base就变成抽象类,无法实例化对象,也就不会触发这个问题;但普通虚函数必须提供定义,哪怕它从未被调用。
内容的提问来源于stack exchange,提问作者yapkm01
相关产品推荐
相关产品推荐

