c++中的声明和定义
Declaration and definition in c++
我认为每个声明都是定义,因为有以下引用来自标准:
声明是定义,除非%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()
{
}
- 如何确保C++函数在定义之前声明(如override关键字)
- 为什么在定义函数之前先声明它
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- Visual Studio中的函数声明和函数定义问题
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 如何在标头中声明(或定义)函数的问题
- 程序顶部的声明与定义(最佳实践)
- 类的前向声明之后的类成员函数定义,在类声明之前
- 静态变量声明和定义
- C++ G++ 编译器 - 错误:隐式声明的定义
- C++:错误重定义和先前声明
- 类模板静态数据成员定义/声明/初始化
- 只有一个定义/声明时标头声明变量的多堆定义错误
- OpenCV - Ptr 语法和类定义/声明 - 混淆?
- 如何为非类型模板类的专用化定义声明之外的方法
- 我如何防止静态类成员变量需要两个定义/声明
- 默认定义声明的详细程度不完整
- C++:非成员函数的定义/声明的位置
- 将比较操作符的重载定义/声明为库中的非成员函数
- C++头重新定义/声明混合