C++列表初始化的存在意义

列表初始化的作用

列表初始化是初始化行为:

1
complex(double r=0,double i=0):re(r),im(i){}

大括号里写叫做赋值行为:

1
complex(double r=0,double i=0){re=r;im=i;}

首先要搞清楚他俩并不是等价的。

没有了列表初始化,仅仅依靠大括号很难解决下面几个问题:

在大括号内无法初始化父类子对象,因为父类子对象没有名字。

是的 这个父类子对象没有名字,我们没法在大括号里直接初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Base{
public:
int a;
int b;
int c;
Base(int x,int y,int z):a(x),b(y),c(z){};
};

class Derived: public Base{
public:
int d,e,f;

//sol1:
Derived(int x,int y,int z):Base(x,y,z),d(x),e(y),f(z){};

//sol2: 错误,这种方法会编译器报错,编译器会让你写出Base的构造函数,因此只能靠第一种列表初始化的方法来构造这个Base。
Derived(int x,int y,int z)
{
a = x;
b = y;
c = z;
d = x;
e = y;
z = z;
}
};

所以委托构造函数也是同理,构造函数是无名的,没法直接调用,因此你还是要用列表初始化,大括号会使得代码臃肿。

引用const变量初始化无法通过大括号初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Base{
public:
const int conVar;
int& ref;
//错误的方法:给const变量,引用都是需要初始化操作的,赋值操作显然不正确。
Base(int x,int& y)
{
conVar = x;
ref = y;
}
//正确的方法
Base(int x,int& y):conVar(x), ref(y)
{

}
};

影响编译器优化性能

image-20221016212103601

综上所述,请尽量使用列表初始化。

Reference:

C++构造函数为什么要依赖初始化列表? - Nessaj的回答 - 知乎 https://www.zhihu.com/question/485487580/answer/2110530722

C++构造函数为什么要依赖初始化列表? - IceBear的回答 - 知乎 https://www.zhihu.com/question/485487580/answer/2110539152