“仅一个实施”规则的例外情况?

时间:2010-06-17 10:42:43

标签: c++ linker definition

在我阅读this question的接受答案时,我有以下问题:

通常,方法在头文件(.hpp或其他)中定义,并在源文件(.cpp或其他)中实现。

包含“源文件”(#include <source_file.cpp>)的不良做法的一个主要原因是它的方法实现会被复制,从而导致链接错误。

当一个人写道:

#ifndef BRITNEYSPEARS_HPP
#define BRITNEYSPEARS_HPP

class BritneySpears
{
  public:

    BritneySpears() {}; // Here the constructor has implementation.
};

#endif /* BRITNEYSPEARS_HPP */

他正在给出构造函数的实现(这里是一个“空”实现,但仍然如此)。

但为什么然后多次包含此头文件(又名在不同的源文件上)会在链接时生成“重复定义”错误?

3 个答案:

答案 0 :(得分:13)

内联函数是“一个定义规则”的例外:允许您在多个编译单元中具有相同的实现。如果函数声明为inline或在类定义中实现,则函数是内联的。

答案 1 :(得分:7)

在类定义中具有实现的成员函数被视为内联函数。内联函数不受一个定义规则的约束。

特别是当链接器看到具有相同签名的两个内联函数时,它将它们视为相同的函数,并且只选择其中一个。这可以导致to really weird hard to detect problems

答案 2 :(得分:2)

因为它是“内联”功能。内联函数可以根据您的喜好多次包含在标题中,并且不会导致重复的定义链接器错误。

编译器也会尝试将它们内联,因此,在上面的示例中,编译器将尝试并完全取消对构造函数的调用。