c++中的声明和定义

Declaration and definition in c++

本文关键字:定义 声明 c++      更新时间:2023-10-16

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

声明是定义,除非%restrictions%

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

class A;
class A;
int main(){ }

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

是的,"除非%restrictions%为真,否则声明就是定义。"你读过限制了吗?其中之一是:

它是一个类名声明

所以class A;不是定义因为它被限制条件之一所覆盖

澄清一下,引用c++ 11, [basic.def]§2

您的引用(来自c++ 113.1/2)回答了一般问题:"除非%restrictions%"意味着不是每个声明都是定义。只有当这些限制都不适用时,它才是一个定义。

如果你阅读了这些限制,你会发现

它是一个类名声明

回答你的具体问题。class A;是类名声明,而不是定义。

我找不到允许在声明性区域中重新声明类类型的部分标准。

一般来说,你可以在同一个声明区域内多次声明一个实体,按照c++ 113.3.4

给定一个声明区域中的一组声明,每个声明都指定了相同的非限定名,它们应该都指向同一个实体,或者[此处不相关的其他情况]

段落§ 3.1.2声明

声明是定义,除非声明的函数没有指定函数体(8.4),它包含外部说明符(7.1.1)或链接规范25(7.5),两者都不是初始化式它不是函数体,而是在类中声明静态数据成员是类名声明(9.1),它是一个不透明的枚举声明(7.2),它是一个模板参数(14.1),它函数声明器中的参数声明(8.3.5)是不是函数定义的声明符,或者它是一个类型定义声明(7.1.3),别名声明(7.1.3),使用声明(7.3.3),一个static_assert声明(第7条),一个属性-声明(第7条)、空声明(第7条)或使用指示(7.3.4)。

这里

class A;
class A;
int main(){ }

是一个类名声明。

语句

声明是定义,除非%限制%。

% %的限制。部分很重要。


我认为每个声明都是定义

让我们用一个矛盾来证明它不成立。假设这是真的。因为我们可以有很多次重新声明每一次声明都是定义我们可以有很多次重新定义,对吧?但是c++标准n3337 § 3.2/1规定

任何翻译单元不得包含一个以上的任何定义变量、函数、类类型、枚举类型或模板

与我们的假设相矛盾,因此并非所有声明都是定义

考虑以下情况:

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()
{
}