我不确定我问的问题是否正确,但让我解释一下。
首先,我阅读了这篇文章,它解释了声明和定义之间的区别:http://www.cprogramming.com/declare_vs_define.html
其次,我从以前的研究中知道,在头文件中定义变量和函数是一种不好的做法,因为在链接阶段,您可能对同一名称有多个定义,这将引发错误。
但是,为什么课堂上没有发生这种情况?根据另一个SO答案(定义和声明有什么区别?),以下将是一个类定义:
class MyClass {
private:
public:
};
如果上述定义在头文件中。然后,大概可以有多个.cpp文件 #include 该标头。 这意味着在多个 .o 文件中编译后多次定义该类,但似乎不会引起太大问题......
另一方面,如果它是在头文件中定义的函数,它显然会导致问题......据我了解...或?
那么类定义有什么特别之处呢?
一个定义规则(3.2,[basic.def.odr])以不同的方式应用于类和函数:
1 - 任何翻译单元都不得包含任何变量、函数、类类型、枚举类型或模板的多个定义。
[...]
4 - 每个程序应只包含该程序中使用的每个非内联函数或变量的一个定义 [...]
因此,虽然(非内联)函数在整个程序中最多可以定义一次(如果调用或以其他方式使用 odr,则恰好定义一次),但类可以定义与翻译单元(源文件)一样多的次数,但每个翻译单元不超过一次。
这样做的原因是,由于类是类型,因此它们的定义对于能够在翻译单元之间共享数据是必要的。 最初,类(C中的struct
s)没有任何需要链接器支持的数据;C++引入了虚拟成员函数和虚拟继承,这需要对 vtable 的链接器支持,但这通常通过将 vtable 附加到成员函数(定义)来解决。
类定义只是该类对象的一种蓝图。自C时代以来,struct
也是如此。代码中实际上不存在任何类或结构。
类定义定义了类,但不定义该类的对象。可以在多个文件中定义类(或结构),因为您只是定义一个类型,而不是该类型的变量。如果您只有定义,编译器将不会发出任何代码。
编译器实际上只有在您声明此类型的对象(即变量)后才会发出代码:
class MyClass myvar;
或:
class MyOtherClass {
public: ...
private: ...
} myvar; // note the variable name, it instantiates a MyOtherClass
这是你不想在标头中做的事情,因为它会导致 myvar 的多个实例被实例化。