码迷,mamicode.com
首页 > 其他好文 > 详细

条款4:确定对象被使用前已被初始化

时间:2017-10-01 15:14:23      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:string   顺序   一个   tle   需要   运算符   文件   extern   区分   

一. 永远在使用对象之前将它初始化

1.对于内置类型,手动完成初始化。
例如:int =0;
2.除了内置类型之外的类型,由构造函数进行初始化:确保每个构造函数都将对象的每一个成员进行了初始化。

二. 特别区分“赋值”和“初始化”

例如:有一个类:A中有一个成员变量string  name;
有一个构造函数:A(const string &n){name=n;}//这是赋值操作而非初始化,这里调用了默认构造函数和赋值运算符
             A(const string &n):name(n){}//这是初始化而非赋值,这里只调用了拷贝构造函数

三. 记住总是使用成员初值列

特别的:如果成员变量是const和reference(引用),就必须需要初值,而不能赋值
Tips:const和reference必须初始化。 

四. 初始化顺序

成员初始化顺序:base  classes总是先于derived  classes被初始化,class的成员变量总是以 其声明顺序被初始化。即便是成员初值列中的顺序不同也是如此。并且,成员初值列中的顺序最好也要按照声明顺序。

五. C++对“定义于不同的编译单元内的non-local  static对象”的初始化相对次序无明确定义

编译单元:指产出单一目标文件的源码。基本上它是单一源码文件加上其所含入的头文件。
static对象:其寿命从被构造出来直到程序结束为止
local static对象:函数内的static对象,其余static对象为non-local static对象。在main()函数
结束时析构函数自动被调用。
例如A,B为两个文件:
class A{
public:
     int A()const;//某个成员函数
};
extern A a;
class B{
public:
     B(params);
};
B::B(params){
      int item=a.A();
}
B b(params);//创建一个类型为B的变量,调用构造函数
class B中的构造函数必须要在A初始化后调用才会有确切的值,否则会出现错误。由于两个是不同的文件,无法确定究竟是谁先被初始化。 
解决方法:利用Singleton模式的一个常见的实现手法(单例)
        将每个non-local static对象搬到自己专属的函数内(在该函数内部声明该对象为static),这些函数返回一个reference指向它所含的对象。
原因:C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对象的定义式”时被初始化。
修改后代码如下:
class A{};
A& a()//用来替换之前的a对象
{
    static A m;     
    return m;
}
class B{};
B::B(params){
      int item=a().A();
}
B& b(){
       static B n;
       return n;
}
 
也就是为免除“跨编译单元的初始化次序”问题,用local static对象替换non-local static对象。

条款4:确定对象被使用前已被初始化

标签:string   顺序   一个   tle   需要   运算符   文件   extern   区分   

原文地址:http://www.cnblogs.com/CoderZSL/p/7617175.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!