大约 2 分钟
为什么要初始化
如果你这么写:
int x;
在某些语境下x保证被初始化(为0),但在其他语境中却不保证
而最佳处理办法就是:永远在使用对象之前先将它初始化。对于无任何成员的内置类型,你必须手工完成此事。例如:
int x = 0; // 对int进行手工初始化
const char* text = "A C-style string"; // 对指针进行手工初始化
// 〔亦见条款3)
double d;
std::cin >> d; // 以读取input stream的方式完成初始化.
别混淆了赋值(assignment)和初始化(initialization)
这个规则很容易奉行,重要的是别混淆了赋值(assignment)和初始化(initialization)。
class PhoneNumber { ... };
class ABEntry { // ABEntry = “Address Book Entry”
public:
ABEntry (const std::string& name, const std::string& address,
const std::list<PhoneNumber>& phones);
private:
std::string theName;
std::string theAddress;
std: :1ist<PhoneNumber> thePhones;
int numTimesConsulted;
};
ABEntry::ABEntry (const std::string& name, const std::string# address,
const std::list<PhoneNumber>& phones)
{
theName = name; // 这 些 都 是 赋 值 (assignments) ,
theAddress = address; // 而 非 初 始 化 (initializations) 。
thePhones = phones;
numTimesConsulted = 0;
}
C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前前。在ABEntry构造函数内,theName,theaddress和thephones都不是被初始化,而是被赋值。初始化的发生时间更早。
ABEntry构造函数的一个较佳与法是,使用所谓的member initialization list (成员初值列) 替换赋值动作
RBEntry::RBEntfYy (const std::stringg name, const std::string& address,
const std::1ist<PhoneNumber>8 phones)
:theName (name) ,
theAddress (address), // 现 在 , 这 些 都 是 初 始 化 (initializations)
thePhones (phones),
numTimesConsulted (0)
{ } // 现 在 , 构 造 函 数 本 体 不 必 有 任 何动 作
所以说,列表初始化 是真正的初始化,会在构造函数前发生。而构造函数内赋值,则只是赋值而已。
假设RBEntry有一个光参数构造出数,我们可将它实现如下:
ABEntry::ABEntry()
:theName () , // 调 用 theName 的 default 构 造 函 数 :
theAddress () , // 为 theaddress 做 类 做 动 作 :
thePhones () , // 为 thePhones 做 类 似 动 作 ;
numTimesConsulted (0) // 记 得 将 numTimesConsul ted 显 式 初 始 化 为 0
{};
C++有着十分固定的“成员初始化次序“。是的,次序总是相同:baseclasses更早于其derivedclasses被初始化(见条款12),而class的成员变量总是以其声明次序被初始化。