Declarations
声明 是将名称引入(或重新引入)C++程序的方式。并非所有声明都会实际声明任何内容,且每种实体的声明方式各不相同。 定义 是指足以使用该名称所标识实体的声明。
声明是以下之一:
|
(since C++11) |
-
空声明 (
;) - 不带 声明说明符序列 的函数声明:
attr
(可选)
declarator
;
|
|||||||||
| attr | - | (since C++11) 任意数量的 属性 序列 |
| declarator | - | 函数声明符 |
- 块声明 (可出现在 块 内部的声明),其本身可以是以下之一:
| (自 C++11 起) |
| (自 C++20 起) | |
| (自 C++11 起) |
-
- 简单声明
目录简单声明简单声明是一条语句,用于引入、创建并可选地初始化一个或多个标识符,通常是变量。
1) 带初始化器的声明符。
2) 不带初始化器的声明符。
说明符声明说明符 ( decl-specifier-seq )是以下空白符分隔的说明符按任意顺序组成的序列:
属性 可以出现在 声明说明符序列 中,此时它们适用于由前序说明符确定的类型。 在 声明说明符序列 中重复任何说明符,例如 const static const 或 virtual inline virtual 均属于错误 ,但允许 long 出现两次的情况除外 (自 C++11 起) 。 声明符每个 init-declarator-list 中的 init-declarator S D1, D2, D3 ; 都会被视为具有相同说明符的独立声明进行处理: S D1 ; S D2 ; S D3 ; 。 每个声明符精确引入一个对象、引用、函数或(对于typedef声明)类型别名,其类型由 decl-specifier-seq 提供,并可选择性地通过声明符中的运算符进行修改,例如 & (引用)或 [ ] (数组)或 ( ) (返回函数)。如下所示,这些运算符可以递归地应用。 一个 声明符 是以下之一:
1)
被声明的
名称
。
10)
括号声明符。
cv 是由 const 与 volatile 限定符组成的序列,其中每个限定符在该序列中最多出现一次。
注释当 块声明 出现在 块内部 时,若声明引入的标识符先前已在外部块中声明,则 外部声明将在该块的剩余部分被隐藏 。 如果声明引入了一个具有自动存储期的变量,该变量会在其声明语句执行时被初始化。所有在块中声明的自动变量都会在退出该块时被销毁(无论该块是通过 异常 、 goto 还是通过到达其末尾退出的),销毁顺序与它们的初始化顺序相反。 示例注意:本示例演示了如何根据语言语法解析某些复杂声明。其他常用的记忆方法包括: 螺旋法则 、 由内向外阅读法 和 声明镜像用法 。另有一个自动解析器位于 https://cdecl.org 。
运行此代码
#include <type_traits> struct S { int member; // 声明说明符序列是 "int" // 声明符是 "member" } obj, *pObj(&obj); // 声明说明符序列是 "struct S { int member; }" // 声明符 "obj" 声明了一个 S 类型的对象 // 声明符 "*pObj" 声明了一个指向 S 的指针, // 且初始化器 "(&obj)" 对其进行了初始化 int i = 1, *p = nullptr, f(), (*pf)(double); // 声明说明符序列是 "int" // 声明符 "i" 声明了一个 int 类型的变量, // 且初始化器 "= 1" 对其进行了初始化 // 声明符 "*p" 声明了一个 int* 类型的变量, // 且初始化器 "= nullptr" 对其进行了初始化 // 声明符 "f()" 声明(但未定义) // 一个不接受参数且返回 int 的函数 // 声明符 "(*pf)(double)" 声明了一个指向函数的指针 // 该函数接受 double 参数并返回 int int (*(*var1)(double))[3] = nullptr; // 声明说明符序列是 "int" // 声明符是 "(*(*var1)(double))[3]" // 初始化器是 "= nullptr" // 1. 声明符 "(*(*var1)(double))[3]" 是一个数组声明符: // 声明的类型是:"(*(*var1)(double))" 3个元素的数组 // 2. 声明符 "(*(*var1)(double))" 是一个指针声明符: // 声明的类型是:"(*var1)(double)" 指向3个元素数组的指针 // 3. 声明符 "(*var1)(double)" 是一个函数声明符: // 声明的类型是:"(*var1)" 接受 "(double)" 参数的函数, // 返回指向3个元素数组的指针 // 4. 声明符 "(*var1)" 是一个指针声明符: // 声明的类型是:"var1" 指向函数的指针,该函数接受 "(double)" 参数, // 返回指向3个元素数组的指针 // 5. 声明符 "var1" 是一个标识符 // 此声明声明了对象 var1,其类型为"指向函数的指针, // 该函数接受 double 参数并返回指向3个 int 类型元素数组的指针" // 初始化器 "= nullptr" 提供了此指针的初始值 // C++11 替代语法: auto (*var2)(double) -> int (*)[3] = nullptr; // 声明说明符序列是 "auto" // 声明符是 "(*var2)(double) -> int (*)[3]" // 初始化器是 "= nullptr" // 1. 声明符 "(*var2)(double) -> int (*)[3]" 是一个函数声明符: // 声明的类型是:"(*var2)" 接受 "(double)" 参数的函数,返回 "int (*)[3]" // ... int main() { static_assert(std::is_same_v<decltype(var1), decltype(var2)>); } 缺陷报告下列行为变更缺陷报告被追溯应用于先前发布的C++标准。
参见
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||