我认为每个声明都是定义,因为标准中有以下引用:
声明是一个定义,除非 %limits% 。
但我的假设不正确。实际上,应用ODR我们有以下程序
class A;
class A;
int main(){ }
是不正确的。但事实并非如此。我无法找到允许在声明区域重新声明类类型的标准的一部分。
答案 0 :(得分:3)
是的,“声明是一个定义,除非%restrictions%”为真。您是否阅读了限制?其中一个是:
这是一个类名声明
所以class A;
不是定义,因为它受到其中一个限制的约束。
只是澄清一下,引用C ++ 11,[basic.def]§2
答案 1 :(得分:1)
段落§ 3.1.2表明
声明是一个定义,除非声明没有的函数 指定函数体(8.4),它包含extern说明符 (7.1.1)或连接规范25(7.5),既不是初始化程序 也不是函数体,它在类中声明了静态数据成员 定义(9.2,9.4),它是一个类名声明(9.1),它是一个 opaque-enum-declaration(7.2),它是一个模板参数(14.1),它 是函数声明符中的参数声明(8.3.5) 不是函数定义的声明者,或者是typedef 声明(7.1.3),别名声明(7.1.3),使用声明 (7.3.3),static_assert-declaration(第7条),属性 - 声明(第7条),空声明(第7条)或a using-directive(7.3.4)。
下面
class A;
class A;
int main(){ }
这是一个类名声明。
在声明中
除非%限制%。
,否则声明是一个定义%limits%。部分非常重要。
我认为每个声明都是定义
让我们通过contradiction证明这不是真的。所以假设这是真的。然后因为我们可以进行许多重新声明,并且每个声明都是定义 - 我们可以有许多重新定义,对吧?但C ++标准版n3337 § 3.2 / 1表示
任何翻译单位不得包含任何一个以上的定义 变量,函数,类类型,枚举类型或模板。
与我们的假设相矛盾,因此每个宣言都是定义并不是真的。
答案 2 :(得分:1)
您的引用(来自C ++ 11 3.1 / 2)回答了一般性问题:"除非 %限制% "意味着不每个声明都是一个定义。如果这些限制都不适用,那么它只是一个定义。
如果你阅读了这些限制,你就会找到
这是一个类名声明
它可以回答您的具体问题。 class A;
是类名声明,但不是定义。
我无法找到允许在声明区域重新声明类类型的标准部分。
通常,您可以在同一个声明区域中多次声明一个实体,每个C ++ 11 3.3.1 / 4
在单个声明性区域中给出一组声明,每个声明都指定相同的非限定名称,它们都应引用同一个实体,或者[此处不相关的其他情况]
答案 3 :(得分:0)
考虑以下情况:
那么header1.h:
class A;
void function1(A * a);
Header2.h:
class A;
void function2(A * a);
的main.cpp
#include "Header1.h"
#include "Header2.h"
#include "A.h" // header file defining A
int main()
{
}
编译器的真实情况是:
class A;
void function1(A * a);
class A;
void function2(A * a);
class A { /* definition from A.h */ };
int main()
{
}