为什么可以在header个文件中定义类?

Why can classes be defined in header files?

根据Why can't I multi-declare a class

class A; is a declaration while

class A { ... } is a definition

通常,在header 文件中,我们定义class 并在.cpp 中实现它的成员函数。但是在 header 文件中定义 classes 不会违反单一定义规则吗?

根据https://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/

Doesn’t defining a class in a header file violate the one-definition rule?

It shouldn’t. If your header file has proper header guards, it shouldn’t be possible to include the class definition more than once into the same file.

Types (which include classes), are exempt from the part of the one-definition rule that says you can only have one definition per program. Therefore, there isn’t an issue #including class definitions into multiple code files (if there was, classes wouldn’t be of much use).

虽然第一部分显然是正确的,header 守卫会阻止在同一个文件中进行多个定义,但我对解决我问题的答案的第二部分感到困惑。

如果 header 文件定义了 class,例如 ThisClass,并且 header 文件包含在另外两个文件中,例如 a.cppb.cpp。为什么它不会违反单一定义规则?如果在任一文件中创建 ThisClass object,将调用哪个定义?

If a header file has a definition of a class, for example ThisClass, and that header file is included in two other files for example a.cpp and b.cpp. Why wouldn't it violate the One Definition Rule?

因为,正如您引用的那样,单一定义规则明确允许这样做。

怎么可能呢?继续阅读……

If a ThisClass object is created in either file, which definition would be called?

没关系,因为定义必须在词法上完全相同。

如果不是,则您的程序具有未定义的行为,您可以预料到随之而来的各种奇怪情况。

根据我正在阅读的内容,使用维基百科对一个定义规则实际上是什么的简要解释可能很重要:

The One Definition Rule (ODR) is an important rule of the C++ programming language that prescribes that objects and non-inline functions cannot have more than one definition in the entire program and template and types cannot have more than one definition by translation unit.

意思是程序编译时,可以有一个并且只有一个 定义函数或对象。这可能令人困惑,但是 classtype 不应被视为对象,它们实际上只是 对象的蓝图

在您的问题中,我认为存在对 #include 的作用以及 ODR 如何应用于 class 的误解。当程序正在编译时,.cpp 文件查看它们的 #include 的 class 定义作为 link 的一种方式,也就是说,class.h blueprint 必须知道在调用它的成员函数时去哪里查找。具有多个 #include 的相同 class.h 与具有多个 class.h 的定义不同,因此,它不会违反 一个定义规则 .

在头文件中定义 class 是可以的,因为在这种情况下,编译器会将 class 中声明的函数视为内联函数。

所以当你调用这个 class 函数时有两种选择:

或者内联函数调用,在这种情况下,多重定义完全没有问题。

或者它不会内联它们,在这种情况下,他会将与函数相关的符号创建为弱符号。然后链接器会选择其中一个符号作为代表函数的符号。

当然,如果两个或多个 cpp 文件中有不同的定义,就会出现未定义的行为。