%%
# 纲要
> 主干纲要、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