%% # 纲要 > 主干纲要、Hint/线索/路标 # Q&A #### 已明确 #### 待明确 > 当下仍存有的疑惑 **❓<font color="#c0504d"> 有什么问题?</font>** %% # 聚合类(Aggregate Class) **聚合类**指代 "满足特定条件"的**类类型**(通常用`struct` 或 `union`声明): - 没有定义任何构造函数 - 所有成员都是 `public` 的 - 没有类内初始值 - 没有基类,也没有虚函数 ```cpp struct Data { int ival; string s; }; Data vall = {0, "Anna"}; // 聚合初始化 ``` 聚合类适用于 "**聚合初始化**" 规则,这种初始化属于"列表初始化"的一种形式。 参见 [[02-开发笔记/01-cpp/cpp 基本概念/cpp-初始化声明#聚合初始化(Aggregate Initialization)|cpp-初始化声明#聚合初始化]] <br><br> # 字面值常量类(Literal Type Class) 字面值常量类(Literal Type Class)是一种特殊类型的类,它 **==允许对象在编译时被创建和初始化==** [^1] (P267)。 这意味着这些**类的对象可以用作常量表达式的一部分**,例如**模板参数或数组维度**。 数据成员都是 "**字面值类型**" 的 **==聚合类==** 本身是 "**字面值常量类**"。 除此之外,一个非聚合类的 "**==常规类类型==**",在**满足以下所有条件**时,也为 "**字面值常量类**": - **==数据成员必须都是字面值类型==**: - 所有的非静态数据成员都必须是字面值类型(如算术类型、引用、指针或其他字面值常量类); - **如果数据成员指定了 "==类内初始值=="**,则该初始值: - 对基本类型的成员,必须是常量表达式; - 对类类型的成员,必须使用其 `constexpr` 构造函数 - **==至少存在一个 `constexpr` 构造函数==**: - `constexpr` 构造函数才能允许在编译时创建和初始化对象。 - 同时,该 `constepxr` 构造函数或"类内初始化" 必须要**确保初始化该类的所有数据成员**——初始值或是常量表达式(对基本类型),或是同样使用`constexpr` 构造函数(对类类型)。 - **==必须使用析构函数的默认定义==**(声明为 `= default`) - 即析构函数不进行任何操作。 > [!NOTE] 构造函数不能是 `const` 的,但字面值常量类的构造函数可以是`constexpr`的。 > > ```cpp > class LiteralTypeClass { // 字面值常量类 > public: > constexpr LiteralTypeClass(int x, int y) : x(x), y(y) {} > constexpr int sum() const { return x + y; } // 编译时求值的函数 > private: > int x, y; > }; > > constexpr LiteralTypeClass obj(1, 2); // 声明字面量类类型对象. 编译时完成 > constexpr int total = obj.sum(); // 编译时完成 > ``` > > <br><br> # 嵌套类 定义在 "**类内部**" 的类,参见 [^2] > [!info] 嵌套类支持 "在类内声明","外层类的外部定义" > > 在外层类的作用域内,嵌套类的名称可见。 > > ```cpp > class MyClass { > public: > class NestedClass; // 声明嵌套类 > // ... > }; > > // 嵌套类 > class MyClass::NestedClass { // 在外层类的外部定义 "嵌套类" > public: > NestedClass(); > }; > > MyClass::NestedClass::NestedClass() {} // 嵌套类的构造函数 > ``` > <br><br> # 局部类 定义在 "**函数内部**" 的类,参见 [^3] 局部类具有下列限制: - 局部类的**成员必须完整定义在==类内部==**。 - 局部类中 **==不允许声明静态成员==**。 - 局部类只能访问外层作用域中的 "**类型名**"、"**静态变量**"、"**枚举值**",**==不能访问外部函数的普通自动变量==**。 说明示例: ```cpp int a, val; void foo(int val) { static int s; enum Loc { a = 1024, b }; // 定义局部类 struct Bar { Loc locVal; int barVal; void fooBar(Loc l = a) { // 正确: 默认实参是a // barVal = val; // error, val是函数形参, 是函数的局部自动变量 barVal = ::val; // 正确: 全局作用域下的全局变量 barVal = si; // 正确: 函数作用域中的静态变量 locVal = b; // 正确: 使用外部作用域的枚举值 } }; } ``` > [!NOTE] 局部类中可以嵌套局部类,嵌套的局部类可在 "**==局部类外部,局部类所在的作用域下定义==**" > > ```cpp > void foo() { > class Bar { // 局部类 > public: > class Nested; // 声明嵌套的局部类 > // ... > }; > > // 定义嵌套的局部类 > class Bar::Nested { > // ... > }; > } > ``` > <br><br> # Buffer ## 闪念 > sudden idea ## 候选资料 > Read it later # ♾️参考资料 # Footnotes [^1]: 《C++ Primer》 [^2]: 《C++ Primer》P746 [^3]: 《C++ Primer》P754