为什么可以在头文件中定义类?
Why can classes be defined in header files?
根据为什么我不能多声明一个类
class A
; 是一个声明,而
class A { ... }
是一个定义
通常,在头文件中,我们定义类并在.cpp
中实现其成员函数。但是,在头文件中定义类不会违反一个定义规则吗?
据 https://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/
在头文件中定义类不违反单定义规则吗?
不应该。如果您的头文件具有适当的标头保护,则 应该不能多次包含类定义 到同一个文件中。
类型(包括类(不受 一个定义规则的一部分,说你只能有一个 每个程序的定义。因此,没有问题 #including 类定义到多个代码文件中(如果有,类 不会有太大用处(。
虽然第一部分显然是正确的,但标头保护将防止同一文件中的多个定义,但我对解决我问题的答案的第二部分感到困惑。
如果头文件具有类的定义,例如ThisClass
,并且该头文件包含在另外两个文件中,例如a.cpp
和b.cpp
。为什么它不会违反一个定义规则?如果在任一文件中创建了ThisClass
对象,将调用哪个定义?
如果头文件具有类的定义,例如 ThisClass,并且该头文件包含在另外两个文件中,例如 a.cpp 和 b.cpp。为什么它不会违反一个定义规则?
因为,正如你引用的,一个定义规则特别允许这样做。
怎么可能?继续阅读...
如果在任一文件中创建了 ThisClass 对象,将调用哪个定义?
没关系,因为定义要求在词汇上绝对相同。
如果不是,你的程序有未定义的行为,你可以期待各种奇怪的事情接踵而至。
根据我正在阅读的内容,使用维基百科对一个定义规则实际上是什么的简要解释可能很重要:
一个定义规则 (ODR( 是C++编程语言的重要规则,它规定对象和非内联函数在整个程序和模板中不能有多个定义,并且类型不能具有多个翻译单元定义。
这意味着在编译程序时,函数或对象可以有一个定义,而且只有一个定义。这可能会令人困惑,但是不应将类或类型视为对象,它们实际上只是对象的蓝图。
在你的问题中,我认为对#include
做什么以及ODR如何应用于类存在误解。当程序编译时,.cpp
文件将#include
类定义视为链接在一起的一种方式,也就是说,class.h
蓝图在调用其成员函数时必须知道在哪里查找。拥有同一class.h
的多个#include
与拥有多个class.h
定义不同,因此,它不能违反一个定义规则。
可以在头文件中定义一个类,因为在这种情况下,编译器会将类中声明的函数视为内联函数。
因此,调用此类函数时,有两种选择:
或者它会内联函数调用,在这种情况下,多重定义完全没有问题。
或者它不会内联它们,在这种情况下,他将与函数相关的符号创建为弱符号。然后,链接器将选择其中一个符号作为表示函数的符号。
当然,如果在两个或多个 cpp 文件中有不同的定义,就会有未定义的行为。
- 告诉CMake链接到自定义文件夹中的Boost
- 通过cMake使用具有自定义文件扩展名的共享库
- 威纳派读取自定义文件或文件夹的所有访问权限
- 使用命令列表解析自定义文件
- 单独的类声明和方法定义文件问题
- Qt解析自定义文件格式
- 将单独的头文件和类定义文件链接到主函数文件 - G++ 返回重载"undefined reference to"构造函数
- FAT32和NTF中的自定义文件属性
- 如何在没有"fatal error: Wt/WApplication: No such file or directory"的情况下将wt安装到自定义文件夹中
- C++ while 循环在自定义文件结构中
- QT C 读取自定义文件结构
- gcc 是否有编译指示来定义文件类型/编译器
- C/C++ 中的跨平台自定义文件头
- 使用头文件和类定义文件时未解决的外部符号错误
- 将此c++代码分解为单独的类规范文件和函数定义文件
- 自定义文件类中fstream对象的生存期
- 如何使用BinaryReader类使用C#读取自定义文件(C++)
- 提供带有libjpeg的自定义文件IO
- C++模块定义文件头内联符号
- 错误:未定义文件中的第一个引用符号