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

Why can classes be defined in header files?

本文关键字:定义 文件 为什么      更新时间:2023-10-16

根据为什么我不能多声明一个类

class A; 是一个声明,而

class A { ... }是一个定义

通常,在头文件中,我们定义类并在.cpp中实现其成员函数。但是,在头文件中定义类不会违反一个定义规则吗?

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

在头文件中定义类不违反单定义规则吗?

不应该。如果您的头文件具有适当的标头保护,则 应该不能多次包含类定义 到同一个文件中。

类型(包括类(不受 一个定义规则的一部分,说你只能有一个 每个程序的定义。因此,没有问题 #including 类定义到多个代码文件中(如果有,类 不会有太大用处(。

虽然第一部分显然是正确的,但标头保护将防止同一文件中的多个定义,但我对解决我问题的答案的第二部分感到困惑。

如果头文件具有类的定义,例如ThisClass,并且该头文件包含在另外两个文件中,例如a.cppb.cpp。为什么它不会违反一个定义规则?如果在任一文件中创建了ThisClass对象,将调用哪个定义?

如果头文件具有类的定义,例如 ThisClass,并且该头文件包含在另外两个文件中,例如 a.cpp 和 b.cpp。为什么它不会违反一个定义规则?

因为,正如你引用的,一个定义规则特别允许这样做。

怎么可能?继续阅读...

如果在任一文件中创建了 ThisClass 对象,将调用哪个定义?

没关系,因为定义要求在词汇上绝对相同。

如果不是,你的程序有未定义的行为,你可以期待各种奇怪的事情接踵而至。

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

一个定义规则 (ODR( 是C++编程语言的重要规则,它规定对象和非内联函数在整个程序和模板中不能有多个定义,并且类型不能具有多个翻译单元定义。

这意味着在编译程序时,函数或对象可以有一个定义,而且只有一个定义。这可能会令人困惑,但是不应将类型视为对象,它们实际上只是对象的蓝图

在你的问题中,我认为对#include做什么以及ODR如何应用于类存在误解。当程序编译时,.cpp文件将#include类定义视为链接在一起的一种方式,也就是说,class.h蓝图在调用其成员函数时必须知道在哪里查找。拥有同一class.h的多个#include与拥有多个class.h定义不同,因此,它不能违反一个定义规则

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

因此,调用此类函数时,有两种选择:

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

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

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