读取未初始化的值会导致未定义行为(undefined behaviour), 确保对象使用时已被初始化。
清楚赋值(assignment)与初始化(initialization)的区别
类成员的初始化时通过构造函数的初始化列表,而不是在构造函数体中。
class ABEntry
{
public:
ABEntry(const std::string& name, cons std::string& address) // 方法1
: theName(name)
, theAddress(address)
, numTimesConsulted(0)
{
}
ABEntry(const std::string& name, cons std::string& address) // 方法2
{
theName = name;
theAddress = address;
numTimesConsulted = 0;
}
private:
std::string theName;
std::string theAddress;
int numTimesConsulted;
}
方法1中通过构造函数的初始化成员列表初始化类成员。
方法2中为先使用各种默认构造函数构造成员,然后再对成员进行赋值。效率更低。
提醒:初始化成员列表中成员的使用顺序应该和成员在类中的声明顺序一直,以免出现不可预测的bug。
不同编译单元中non-local static对象的初始化次序
对于定义在不同的编译单元内的non-local static对象的初始化相对次序并无明确定义。
使用local static对象替代,即通过单例模式(Singleton)解决:
class Item { ... };
Item& GetItem()
{
static Item one; // local static
return one;
}
请记住:
- 为内置对象进行手工初始化,因为C++不保证初始化它们。
- 构造函数最好使用成员初始化列表(member initialization list), 而不要在构造函数体内使用赋值,初始化列表中的列出的变量顺序,应该和它们在class中的声明顺序相同。
- 为免除“跨编译单元之初始化次序”问题,请以local static对象替换 non-local static对象