确定对象被使用前已经被初始化

2018-06-17 23:34:54来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

在C part of C++中,声明一个变量,不一定会被初始化,而一旦进入non-C part of C++,规则有些变化。这就很好的解释了为什么array(来自C part of C++)不被初始化而vector却有此保证(来自STL of C++)。

    
    表面上这似乎是个无法决定的状态,而最佳处理方法是:永远在使用对象前将它初始化。对于无任何成员的内置类型,你必须手工完成此事
   
  1. int x=0;
  2. constchar* text ="A C-style string";
  3. double d;
  4. std::cin >> d;
 
    至于内置类型以外的任何其他东西,则需要构造函数来初始化。规则就是:确保每一个构造函数都将对象的每一个成员初始化。
这个规则很简单,但不要混淆了赋值和初始化。
 
  1. classMoney{
  2. public:
  3. Money();
  4. private:
  5. int thecash;
  6. }
  7. Money::Money(constint cash)
  8. {
  9. thecash = cash;//这是赋值,不是初始化
  10. }
  11. Money::Money(constint cash):thecash(cash)//这才是初始化
  12. {}
 
第二个构造函数相比第一个,最终结果相同,但通常效率更高。第一个版本先调用默认构造函数设置初始值,然后再立刻对他们赋值,第二个则省去了调用默认构造函数的步骤,直接使用实参初始化。
 
 
________________________________________________________________________________________________
 
 
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。
_________________________________________________________________________________________________
  1. a.cpp
  2. class A{
  3. public:
  4. std::size_t num()const;
  5. };
  6. extern A aa;
 
__________________________________________________________________________________________________
 
__________________________________________________________________________________________________
  1. b.cpp
  2. class B{
  3. public:
  4. B();
  5. };
  6. B::B()
  7. {
  8. std::size_t disk = aa.num();//调用aa对象
  9. }
  10. B bb;//创建bb对象
 
___________________________________________________________________________________________________
 
由于C++对于不同编译单元中的non-local static对象初始化次序没有明确规定,假如bb先于aa被初始化,则它将用到还未被初始化的aa,
这显然是不可取的做法。
 
解决之道是将aa对象搬到专属函数内。
 
—————————————————————————————————————————————————————————
  1. a.cpp
  2. class A{…};
  3. A& aa()
  4. {
  5. static A a;
  6. return a;
  7. }
 
—————————————————————————————————————————————————————————
 
—————————————————————————————————————————————————————————
  1. b.cpp
  2. class B{…}
  3. B::B()
  4. {
  5. std::size_t disk = aa().num();
  6. }
  7. B bb;//创建bb对象
 
 
—————————————————————————————————————————————————————————
 
这样修改之后,在初始化bb对象时,必然调用aa(),进而保证了aa对象先被初始化。
 


参考资料:《Effective C++》

来自为知笔记(Wiz)



标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:[C++]实现散列表的分离链接法的数据结构

下一篇:热敏打印机编程