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


