Effective C++ 第四條 確定對象被使用前以先被初始化

  • 爲內置對象進行手工初始化,C++不保證初始化它們

    確保每一個構造函數都將對象的每一個成員初始化。

#include <iostream>
using namespace std;
#include <string>

class  Test {
public:
    Test(const string &str, const string& add, int num)
    {
        name = str;       //這些都是賦值,非初始化,初始化發生在函數體之前
        theaddress = add;
        number = num;
    }

private:
    string name;
    string theaddress;
    int number;
};

這種寫法會調用default的構造函數爲成員初始化,然後立刻賦值,雖然得到結果正確,但是效率不如下面的。

    Test(const string &str, const string& add, int num)
        :name(str)
        ,theaddress(add)
        ,number(num)
    {}

無參的構造函數初始化

    Test()
        :name()
        ,theaddress()
        ,number(0)
    {}

const成員和reference一定得在初始化列表中完成,base class總是早於derived class被初始化。 class成員總是以成員聲明的順序初始化。

  • 不同編譯單元內定義的non_local static對象初始化次序。
    static對象,其壽命從被構造函數直到程序結束爲止。(heap, stack對象被除)。包括global對象,namespace作用域內的對象,還有函數類內,file作用域中,class中被聲明爲static對象被稱爲 static對象。函數內的static對象稱爲local-static對象。 其他的稱爲static對象稱爲non-local static對象
    如果有兩個源文件,每一至少含有一個non-local static對象。
class FileSystem   //程序庫
{
    ...
        size_t numDisks() const;
    ...
};

extern FileSystem tfs;  //預備給客戶使用的對象

C++中對於定義在不同編譯單元內的non-local static對象的初始化次序沒有明確定義。而客戶端如果使用tfs對象。可能tfs還沒有初始化,就可能發生錯誤。Director temp(tfs.numDisks()) // 可戶用tfs的函數初始化自己的目錄,但是tfs可能還沒有初始化
解決方法:

FileSystem &tfs()
{
    static FileSystem fs;   
    return fs;
}

用local static 對象代替 non-local static對象。如果使用頻繁可以設爲inline函數。這樣就可以解決non-local static對象的初始化順序問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章