C++ 为什么在头文件中定义类时没有多个定义错误?

C++ 为什么在头文件中定义类时没有多个定义错误?,c++,linker,header-files,one-definition-rule,C++,Linker,Header Files,One Definition Rule,我不确定我问的问题是否正确,但让我解释一下 首先,我阅读了这篇解释声明和定义之间区别的文章: 其次,我从以前的研究中了解到,在头文件中定义变量和函数是一种不好的做法,因为在链接阶段,可能会对同一个名称有多个定义,这会引发错误 然而,为什么这不会发生在课堂上呢?根据另一个答案( ),以下是类定义: class MyClass { private: public: }; 如果上面的定义在头文件中。然后,大概可以有多个包含该头的.cpp文件。这意味着

我不确定我问的问题是否正确,但让我解释一下

首先,我阅读了这篇解释声明和定义之间区别的文章:

其次,我从以前的研究中了解到,在头文件中定义变量和函数是一种不好的做法,因为在链接阶段,可能会对同一个名称有多个定义,这会引发错误

然而,为什么这不会发生在课堂上呢?根据另一个答案( ),以下是类定义:

    class MyClass {
        private:
        public:
    };
如果上面的定义在头文件中。然后,大概可以有多个包含该头的.cpp文件。这意味着该类在多个.o文件中编译后被多次定义,但似乎不会引起太多问题

另一方面,如果它是在头文件中定义的函数,它显然会导致问题…据我所知。。。也许吧


那么类定义有什么特别之处呢?

一个定义规则(3.2,[basic.def.odr])适用于不同的类和函数:

1-任何翻译单元不得包含任何变量、函数、类类型、枚举类型或模板的多个定义

[……]

4-每个程序应仅包含该程序中使用的odr的每个非内联函数或变量的一个定义[…]

因此,虽然(非内联)函数在整个程序中最多只能定义一次(如果调用或以其他方式使用odr,则只能定义一次),但类的定义次数可能与具有翻译单元(源文件)的次数相同,但每个翻译单元最多只能定义一次


这样做的原因是,由于类是类型,它们的定义对于能够在翻译单元之间共享数据是必需的。最初,类(C中的
struct
s)没有任何需要链接器支持的数据;C++引入虚拟成员函数和虚拟继承,这需要链接表支持VTABLE,但通常通过将VTALE附加到成员函数(定义)来解决。

< P>类定义只是该类对象的蓝图。自从C时代以来,
struct
就一直如此。代码中实际上不存在这样的类或结构。

您的类定义定义了该类,但没有定义该类的类和对象。可以在多个文件中定义类(或结构),因为您只是定义一个类型,而不是该类型的变量。如果您刚刚有了定义,编译器将不会发出任何代码。
编译器实际上只有在您声明此类型的对象(即变量)后才会发出代码:

class MyClass myvar;
或:


这是您不希望在头文件中执行的操作,因为这将导致myvar的多个实例被实例化。

头文件是否有头保护?它们有。但是,据我所知,头保护仅针对同一源文件()中的多个定义进行保护。这个问题主要涉及多个源文件包含同一个头的情况。我不喜欢这个答案,因为函数也可以使用类似的参数:“函数定义定义函数,但不调用它。”!
class MyOtherClass { 
    public: ...
    private: ...
} myvar;         // note the variable name, it instantiates a MyOtherClass