虽然还有其他关于堆栈溢出的问题,它们处理'未定义引用vtable'错误消息。下面的代码要么编译,要么不编译,这取决于无参数构造函数C()是否在线实现。我知道成员函数m()应该是纯虚拟的,这将是修正问题的正确改变。我感到困惑的是,它可以用一种明显无关的变化进行编译。对内联构造函数影响的vtable错误的未定义引用
下面的代码不能用g ++(ubuntu 64位上的4.6.3)进行编译,并产生预期的'未定义的引用vtable for C'消息(对于记录来说仍然是一个可怕的错误信息,考虑到问题是米())
Header.h
#ifndef HEADER_H
#define HEADER_H
class C
{
public:
C();
virtual void m();
};
#endif
Implementation.cpp
#include "Header.h"
C::C() {}
Main.cpp的
次#include "Header.h"
int main()
{
return 0;
}
以下无关修改允许编译:
- 对于C :: C来自Implementation.cpp删除非直列实现()
- 添加琐碎在线实现对C ()to Header.h中的类
这是为什么允许编译?这是编译器错误,优化器问题还是标准惊喜的黑暗角落?
+1,虽然*为什么建设过程中需要的虚函数表的*复杂的原因很简单:编译器必须设置'vptr'指向它:) –
是的,ABI使它听起来很复杂,但就是这样! :) –
我其实在那里做了一些手势。在这个特殊情况下,它就如此简单,但ABI必须处理所有使其更加复杂的情况。例如,考虑创建派生类型。虽然起初看起来并不明显,但即使没有创建基类型的对象,也需要基类的vtable。 –