您可以自由地共享和演绎本文稿, 只需遵守开源协议[CC By 4.0]
如果这篇文章帮助到你, 可以请我喝一杯咖啡~
这是Effective C++的学习记录。
条款04:保证调用实例之前初始化
在使用实例或变量之前保证它是有初值的。这可以通过在构造函数中加入委托构造函数来实现。
区分赋值和初始化
class example {
int a;
public:
example() { a = 1; } //这是赋值
}
class example {
int a;
public:
example() : a(1){} //这是初始化
example() : { a(1); } //这是初始化,但不推荐使用
}
那么这两种写法有什么区别呢?
在构造函数被调用时,程序首先检查委托构造函数列表,以带初值的形式调用成员的构造函数,随后以无初值的形式调用未委托构造的成员的构造函数。
这就导致了,如果使用第一个程序,程序会首先为a开辟一个内存空间,再将1赋值进去。而第二个程序,程序会直接以1为初值开辟一个内存空间,这在开销上可能会更优一点。因此,使用委托构造而不是在构造函数中赋值。
委托构造函数的构造顺序
首先调用的是基类的构造函数。
在同一个类的继承迭代层级中,构造函数将按照委托构造列中的顺序调用。
如果某些成员的初值与另一些成员的值相关,就需要格外注意这一点。
但是,C++对于不同编译单元内(比如不同的文件)的对象初始化顺序并未明确定义。这个问题可以通过使用返回实例引用的函数,应用匿名类解决。
example& LEName() {
static example temp;
return temp;
}
应用如上程序,用户只需要调用LEName()即可取代之前的不知道是否初始化过的example实例。