链接器如何处理多个头文件中定义的虚函数?

时间:2013-02-08 14:46:50

标签: c++ linker polymorphism

假设我有

Base.h
class Base
{
    virtual void foo() {...}
};


Derived1.h
class Derived1 : public Base
{
    virtual void foo() {...}
};


Derived2.h
class Derived2 : public Base
{
    virtual void foo() {...}
};

标题Derived1.h包含在多个源文件中,Derived1类也通过Base接口使用。由于foovirtual且使用polymorphic,因此无法内联。因此它将被编译为多个obj文件。然后,链接器如何解决这种情况?

1 个答案:

答案 0 :(得分:5)

类定义中定义的成员函数是隐式inline C ++ 03 7.1.2.3 )。
函数体是否实际上在调用时被内联是无关紧要的。但是inline允许您拥有函数的多个定义,只要所有定义都相同(一个定义规则不允许)( C ++ 03 7.1.2.2 )。标准规定链接器应该能够链接到(一个或多个)这些定义。( C ++ 03 7.1.2.4 )。

  

链接器如何做到这一点?

对此的标准规定:

  • 它要求功能定义应存在于每个翻译单元中。链接器所要做的就是链接到该转换单元中的定义。
  • 它要求此函数的所有定义应完全相同,如果存在不同的定义,这将消除链接到特定定义的任何歧义。

C ++ 03 7.1.2函数说明符:
第2段:

  

带有内联说明符的函数声明(8.3.5,9.3,11.4)声明了一个内联函数。内联说明符向实现指示在调用点处函数体的内联替换优先于通常的函数调用机制。在呼叫点执行此内联替换不需要实现;但是,即使省略了这种内联替换,仍应遵守7.1.2定义的内联函数的其他规则。

第3段:

  

类定义中定义的函数是内联函数。内联说明符不应出现在块作用域函数声明

第4段:

  

内联函数应在每个使用它的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。