c ++中的声明和定义

时间:2014-05-14 12:04:34

标签: c++ language-lawyer

我认为每个声明都是定义,因为标准中有以下引用:

  

声明是一个定义,除非 %limits%

但我的假设不正确。实际上,应用ODR我们有以下程序

class A;
class A;

int main(){ }

是不正确的。但事实并非如此。我无法找到允许在声明区域重新声明类类型的标准的一部分。

4 个答案:

答案 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()
{

}