确定对象试用前已经初始化(Effective C++_4)

读取未初始化的值会导致不明确的行为。最佳处理办法:永远在使用对象之前将它初始化。

区分赋值(assignment)和初始化(initialization)。

class Sample{

public:

    Sample(const std::string& name);

private:

    std::string theName;

    int num;

}

Sample::Sample(const std::string& name)

{

    theName = name;    //这些都是赋值

    num = 0;

}

C++规定,对象的成员变量的初始化发生在进入构造函数本体之前。

在Sample构造函数内,theName不是初始化,是赋值。初始化的发生时间更早,发生在这些成员的default构造函数被自动调用之前。表明,先进行了调用构造函数的动作,然后进入函数体了调用了赋值操作,那么之前的构造操作浪费了;但这对num不为真,因为它属于内置类型(就是c/c++中最基本的类型,如int, char,float等都是),不保证在赋值动作的时间点之前获得初值。

Sample构造函数较佳写法是使用所谓的member initialization list(成员初值列)替换赋值动作。

Sample::Sample(const std::string& name)

:theName(name),

num(0)

{}

上面的写法,只调用了copy构造,很明显效率比之前的代码要高,没有进行赋值操作;
*有些情况下即使面对的成员变量属于内置类型(那么其初始化与赋值的成本相同),也一定得使用初值列。是的,如果成员变量时const或references,它们就一定需要初值,不能被赋值。为避免需要记住成员变量何时必须在成员初值列中初始化,何时不需要,最简单的做法就是:总是使用成员初值列*。这往往比赋值更高效。

许多classes有多个构造函数,每个构造函数有自己的初值列。如果这种class有许多成员变量和/或base classes,多份初值列导致重复和无聊的工作。这时可以再初值列中遗漏“赋值和初始化一样好”的成员变量,改用它们的赋值操作,并把这些赋值操作移往某个函数(通常是private),供所有构造函数调用,这种做法在“成员变量的初值系由文件或数据库读入”时特别有用。然而,比起经由赋值操作完成的“伪初始化”,通过成员初值列完成的“真正初始化”通常更加可取。

C++有着十分固定的“成员初始化次序”。是的,次序总是相同的:base classes更早与其derived classes被初始化。而class的成员变量总是以其声明次序被初始化。为避免你或你的检阅者迷惑,并避免某些可能存在的晦涩错误,在成员初值列中条列各个成员时,最好总是以其声明次序为次序。

总结:
1.为内置型对象进行手工初始化,因为c++不保证初始化它们

2.构造函数最好使用成员初值列,而不要在构造函数本体内使用赋值操作。初值列列出来的成员变量,其排列次序应该和他们在class中声明次序相同。

3.为避免“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象


转载地址:http://m.blog.csdn.net/blog/zzpalm/4740121

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值