列表初始化
内置类型初始化
int x{2};
int x1 = 2;
自定义类型初始化
- 直接构造:本质是先构造一个 Date 临时对象,再拷贝构造 d1;但编译器会优化这个过程,直接用列表参数构造 d1(即不会调用拷贝构造函数)。
// 2. 自定义类型(类)的列表初始化
Date d1 = {2025, 11, 01};
Date d2{2025, 05, 28};
- 绑定引用初始化:列表
{2025, 12, 12}会先构造一个 Date 临时对象,然后将这个临时对象的引用绑定到 const 引用 d3(或 d4)上。因为临时对象的生命周期会被延长,与 const 引用的生命周期一致,所以这种写法是合法的。
const Date& d3 = {2025, 12, 12};
const Date& d4{2025, 12, 12};
// Date& d4{ 2025, 12, 12 }; // 临时对象 { 2025, 12, 12 } 被绑定到 const 引用 d4,生命周期延长至 d4 的作用域结束
问题:const Date& d4(2025, 10, 10) 为什么一定要加 const,const 意义何在? 如果不加 const,就是非 const 引用,会报错。原因在于非 const 引用意味着可以修改内部的数据,但是受生命周期影响,被引用&的内容出了作用域就会销毁,再去修改内部的数据,就会报错。加 const 一来可以防止内部的数据被修改,二来可以让 d4 一直坚持到生命周期结束再销毁。 'const 引用可以延长临时对象的生命周期,使其与引用自身的生命周期一致',这样就避免了'对象提前销毁导致引用失效'的问题。 简单总结一下:临时对象匿名对象的生命周期都只在一行,const 引用可以延长临时对象 + 匿名对象的生命周期。
非 const 引用 + 临时对象 → 语法禁止(因为修改无意义且危险); const 引用 + 临时对象 → 语法允许,且延长临时对象生命周期至引用销毁。
注意一个小点:只有 { } 初始化才可以省略 =。像 Date d 2025; 一定会报错。
结合析构函数(复习巩固)
局部对象和被 const 引用延长生命周期的临时对象,析构顺序与构造顺序相反(即'先构造的后析构,后构造的先析构')。 在这段代码中,构造顺序大致是:d1 → d2 → d3 → d4;因此析构顺序是:d4 → d3 → d2 → d1,与打印的顺序完全一致。
// 构造
vector<int> v1 = {1, , , , , };
vector<> v2{, , , , , };
vector<>& v3 = {, , , , , };
;
;


