为什么要编译,而不是链接?

Bar*_*uch 2 c++ virtual linker

#include <iostream>
using namespace std;

class C
{
public:
    virtual void a();
};

class D : public C
{
public:
    void a() { cout<<"D::a\n"; }
    void b() { cout<<"D::b\n"; }
};

int main()
{
    D a;
    a.b();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我收到链接错误undefined reference to 'vtable for C'.这是什么意思,为什么呢?

我知道问题显然是基类有一个永远不会定义的非纯虚函数,但是如果我从不调用它,为什么这会打扰链接器呢?为什么它与我声明和未定义的任何其他功能不同,如果我从不称呼它我很好?
我对细节感兴趣.

Gre*_*ill 9

大多数C++编译器的实现为每个类生成一个vtable,这是一个虚函数的函数指针表.与任何其他数据项一样,vtable只能有一个定义.一些C++编译器在编译类型中第一个声明的虚函数的实现时生成此vtable (这保证了vtable只有一个定义).如果您未能为第一个虚函数提供实现,则编译器不会生成vtable,并且链接器会抱怨缺少vtable并出现链接错误.

如您所见,具体细节取决于所选编译器和链接器的实现.并非所有工具链都相同.

  • 编译器必须生成完整的vtable,因为它不知道你是否可以从某些*其他*C++源文件(编译器没有看到)调用它.链接器相当愚蠢,只是尝试将引用与编译器指定的定义连接起来. (2认同)