16

我不确定我是否正确地提出了这个问题,但让我解释一下。

首先,我阅读了这篇解释声明和定义之间区别的文章: http ://www.cprogramming.com/declare_vs_define.html

其次,我从之前的研究中知道,在头文件中定义变量和函数是不好的做法,因为在链接阶段,您可能有多个同名定义,这会引发错误。

但是,为什么上课不会发生这种情况?根据另一个SO答案( 定义和声明之间有什么区别?),以下将是一个类定义:

    class MyClass {
        private:
        public:
    };

如果上面的定义在头文件中。然后,据推测,您可以拥有多个 #include 该标头的 .cpp 文件。这意味着该类在多个 .o 文件中编译后多次定义,但似乎不会造成太多问题......

另一方面,如果它是在头文件中定义的函数,它显然会导致问题......据我了解......也许?

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

4

3 回答 3

16

单一定义规则(3.2,[basic.def.odr])以不同的方式应用于类和函数:

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

[...]

4 - 每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义 [...]

因此,虽然(非内联)函数在整个程序中最多可以定义一次(如果它们被调用或以其他方式使用,则只能定义一次),类可以定义与翻译单元(源文件)一样多次,但每个翻译单元不超过一次。

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

于 2013-02-01T20:27:24.230 回答
1

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

于 2013-02-01T20:27:30.020 回答
0

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

class MyClass myvar;

或者:

class MyOtherClass { 
    public: ...
    private: ...
} myvar;         // note the variable name, it instantiates a MyOtherClass

这就是你不想在标题中做的事情,因为它会导致myvar的多个实例被实例化。

于 2013-02-01T20:34:10.393 回答