确定对象被使用前巳先被初始化

来源:互联网 发布:北斗网络时间服务器 编辑:程序博客网 时间:2024/06/18 00:30

 

通常如果你使用C part of C++  而且初始化可能招致运行期成本,
那么就不保证发生初始化。一旦进入non-C part ofC ,规则有些变化。这就很好
地解释了为什么array (来自C part of C++ )不保证其内容被初始化,而vector (来
自STLpart ofC++) 却有此保证。

 

 

表面上这似乎是个无法决定的状态,而最佳处理办法就是:永远在使用对象之
前先将它初始化。对于无任何成员的内置类型,你必须手工完成此事。例z如
int x = 0;
const char* text = "A C-style string";
double d;

 std::cin » d; //以读取input  的方式完成初始化
至于内置类型以外的任何其他东西,初始化责任落在构造函数( constructors)
身上。规则很简单:确保每一个构造函数都将对象的每一个成员初始化。

 

 

 

这个规则很容易奉行,重要的是别混淆了赋值 和初始化
( initialization) 。考虑一个用来表现通讯簿的class ,其构造函数如下:
class PhoneNumber { ... };
class ABEntry { IIABEntry =叽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::list<PhoneNumber> thePhones;
int numTimesConsulted;
ABEntry: :ABEntry(const std: :string& n缸ne , const std: : string& address,
const std::list<PhoneNumber>& phones)
theName 二口arne; //这些都是赋值(assignments) ,
theAddress = address; //始化(initializations)。
thePhones = phones;
numTimesConsulted = 0;

 

这会导致ABEntry 对象带有你期望(你指定)的值,但不是最佳做法。C++ 规
,对象的成员变量的初始化动作发生在进入构造函数本体之前。在ABEntry 构造
函数内, theNarr吼theAddress 和thePhones 都不是被初始化,而是被赋值。初始
化的发生时间更早,发生于这些成员的default 构造函数被自动调用之时(比进入
ABEntry 构造函数本体的时间更早)。但这对numTimesConsu1ted 不为真,因为它
属于内置类型,不保证一定在你所看到的那个赋值动作的时间点之前获得初值。

 

ABEntry 构造函数的一个较佳写法是,使用所谓的member initialization list (成
员初值列〉替换赋值动作:
ABEntry: :ABEntry(const std: :string& n缸ne , const std: :string& address,
const std::1ist<PhoneNumber>& phones)
:theNarne(narne) ,
theAddress(address) , //现在,这些都是初始化(initializations )
thePhones(phones) ,
numTimesConsu1ted(O)
( } //现在,构造函数本体不必有任何动作

 

这个构造函数和上一个的最终结果相同,但通常效率较高。基于赋值的那个版
本(本例第一版本)首先调用default 构造函数为theNarne, theAddress 和thePhones
设初值,然后立刻再对它们赋予新值。default 构造函数的一切作为因此浪费了。成
员初值列(member initialization list) 的做法(本例第二版本)避免了这一问题,因
为初值列中针对各个成员变量而设的实参,被拿去作为各成员变量之构造函数的实
参。本例中的theNarne 以name为初值进行copy构造, theAddress 以address 为
初值进行copy构造, thePhones 以phones 为初值进行copy构造。

 

规则:
规定总是在初值列中列出所有成员变量,以免还得记住哪些成员变量(如果它们在
初值列中被遗漏的话〉可以无需初值。