c++ - header 和 ODR 中的类定义?

标签 c++

因此我们将类定义放在标题中,并且由于 ODR(可能还有更多原因),我们不包括翻译单元而不是标题。此外,由于 ODR,您不应在 header 中添加变量和函数等的定义,因为它可能会违反规则....

但是自ODR also applies for class types (对我来说是类定义),为什么可以在不小心的情况下将其添加到标题中?

最佳答案

标准的“3.2 Ondefinition 规则”部分有几条陈述,涵盖了规则的不同方面。

  1. No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

这涵盖了您问题中的类类型定义,但这仅适用于一个翻译单元(或源文件)。不同文件(翻译单元)中包含的 header 中的相同类类型定义不违反这一点,因为它涉及多个翻译单元(并且在任何一个翻译单元中仍然只有一个定义)。

  1. Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in which it is odr-used.

此规则涵盖程序级别(可能包含多个翻译单元),但它仅影响使用 odr 的非内联函数或可行。包含在不同翻译单元中的类类型定义不包括在内,不违反此规则。

并且,有一条规则专门处理出现在不同翻译单元中的类类型的定义:

  1. There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then

    • each definition of D shall consist of the same sequence of tokens; and
    • in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), except that a name can refer to a const object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D; and
    • in each definition of D, corresponding entities shall have the same language linkage; and
    • in each definition of D, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same function, or to a function defined within the definition of D; and
    • in each definition of D, a default argument used by an (implicit or explicit) function call is treated as if its token sequence were present in the definition of D; that is, the default argument is subject to the three requirements described above (and, if the default argument has sub-expressions with default arguments, this requirement applies recursively).
    • if D is a class with an implicitly-declared constructor (12.1), it is as if the constructor was implicitly defined in every translation unit where it is odr-used, and the implicit definition in every translation unit shall call the same constructor for a base class or a class member of D.

简而言之,您可以在不同的翻译单元中多次定义类类型,但每个翻译单元最多只能有一个定义,并且所有定义必须相同。

关于c++ - header 和 ODR 中的类定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900040/

相关文章:

c++ - 不同的 32 位转换为 long/__int64,为什么?

c++ - 在我自己的类中捕获并处理所有异常

c++ - 将原始指针视为基于范围的 for 循环中的范围

java - 线程程序规范的含义

c++ - libuv 工作线程或工作队列健康检查?

c++ - 遍历 C++ 映射时的奇怪行为

c++ - 从纯虚拟(接口(interface))类虚拟继承是一个很好的约定吗?

c++ - 为什么这个 Windows 消息循环不处理快捷键/tab 键?

c++ - Bad_alloc 声明数组时,似乎内存不够

c++ - 搜索\n 和\t