《Effective C艹》读书笔记(3)

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

    读取未初始化的值会导致程序发生不明确的行为。对于内置类型以外的其他任何类型,初始化的责任落在了构造函数身上。

    在落实这个规则的时候要注意,不要混淆了赋值和初始化 。

    

class ca{
    int a;
};
class cb{
    int a;
    string b;
    vector<ca> c;
    cb(const int& aa,const string& bb,const vector<ca> cc){
        a=aa;           //这些都是赋值!
        b=bb;           //而不是初始化!
        c=cc;
    }
};

     对于上面的程序,并不是高效率的做法,在构造函数内,变量都不是被初始化,而是被赋值(内置类型除外)。这意味着,首先调用默认的构造函数来为bb,cc设初值,然后再立刻为他们赋值。默认构造函数所做的工作就被浪费了。

    一种更好的写法是使用成员初值列,代码如下

class cb{
    int a;
    string b;
    vector<ca> c;
    cb(const int& aa,const string& bb,const vector<ca> cc):
        a(aa),
        b(bb),
        c(cc){}
};

     对于大多数类型而言,比起现调用default构造函数再调用赋值操作符,单调用一次copy构造函数是更高效的。

    请立下一个规则,规定总是在初值列中列出所有的成员变量,以避免某些变量未被初始化。

    有些情况下,即使面对的成员变量是内置类型,也必须要用初值列,而不能被赋值(例如const变量和引用变量)。

    class内变量初始化的顺序总是和他们在类内声明的顺序是相同的。为了方便阅读,在成员初值列中列出各个成员时,总是按照其声明的次序为次序。

    请以local static代替non-local static。

    例如我们在文件1中定义 int a = 1;

           我们在文件2中定义 extern int a;int b = a*3;

     如果文件2在文件1之前被调用,那么b值就有可能是垃圾值。为了避免这种问题,我们应该避免使变量具有全局的作用域 ,具体的做法就是以local static来代替non-local static,代码如下

int& getA(){  //文件1中
    static int a = 1;
    return a;
}

int b = getA()*3;//文件2中

 这样做就能保证a的初始化在前了

猜你喜欢

转载自bbezxcy.iteye.com/blog/2240635