effective C++读书笔记 条款四 确定对象被使用前已经被初始化

在C part of C++中,声明一个变量,不一定会被初始化,而一旦进入non-C part of C++,规则有些变化。这就很好的解释了为什么array(来自C part of C++)不被初始化而vector却有此保证(来自STL of C++)。
    
    表面上这似乎是个无法决定的状态,而最佳处理方法是:永远在使用对象前将它初始化。对于无任何成员的内置类型,你必须手工完成此事。
int x=0;
const char* text = "A C-style string";

double d;
std::cin >> d;

 至于内置类型以外的任何其他东西,则需要构造函数来初始化。规则就是:确保每一个构造函数都将对象的每一个成员初始化。
这个规则很简单,但不要混淆了赋值和初始化。
class Money{
public:
    Money();
private:
    int thecash;
}
Money::Money(const int cash)
{
    thecash = cash;  //这是赋值,不是初始化
}

Money::Money(const int cash):thecash(cash)         //这才是初始化
{}

第二个构造函数相比第一个,最终结果相同,但通常效率更高。第一个版本先调用默认构造函数设置初始值,然后再立刻对他们赋值,第二个则省去了调用默认构造函数的步骤,直接使用实参初始化。

________________________________________________________________________________________________


C++有着十分固定的成员初始化次序:base classes更早于其derived classes被初始化,而class成员变量总是以其声明次序被初始化。即使它们在成员初值列中以不同次序出现(很不幸那是合法的),也不会有任何影响。

———————————————————————————————————————————————————————

   
还有一件事情需要操心,即:不同编译单元内定义的non-local static对象的初始化次序


static对象包括:global对象,定义于namespace作用域的对象,在class内、在函数内、以及在文件作用域内被声明为static的对象。
函数内的被称为local static对象,其他的都是non-local static对象。

多个编译单元中的non-local static对象的编译次序C++并未做明确的规定


考虑如下两个文件 a.cpp,b.cpp。
a.cpp

class A{
public:
        std::size_t num() const;
};
extern A aa;


b.cpp

class B{
public:
      B();
};
B::B()
{
        std::size_t disk = aa.num();           //调用aa对象
}

B bb;  //创建bb对象

由于C++对于不同编译单元中的non-local static对象初始化次序没有明确规定,假如bb先于aa被初始化,则它将用到还未被初始化的aa,
这显然是不可取的做法。

解决之道是将aa对象搬到专属函数内。

a.cpp

class A{…};
A& aa()
{
    static A a;
    return a;
}

b.cpp

class B{…}
B::B()
{
    std::size_t disk = aa().num();
}

B bb;  //创建bb对象
这样修改之后,在初始化bb对象时,必然调用aa(),进而保证了aa对象 先被初始化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值