讀書筆記《Effective c++》 條款04 確定對象被使用前已經被初始化


a.對於內置類型,必須手工完成初始化,對於除此以外的東西,初始化的責任落在構造函數上。


  (疑問:書上說如果在帶參構造函數中給成員賦值而不是使用初始化列表的話,會首先調用default構造函數爲成員設初始值,然後立刻對他們賦予新值,但在我只的測試代碼中,default構造函數並沒有被調用,這裏我的理解是,可能並不是調用default構造函數,而是調用了和default構造函數相同的底層函數)


  當然,最簡單並且應該的做法是,永遠使用初始化列表來初始化成員變量。

  在實際項目中,一個class可能有多個構造函數,每個構造函數都有自己的初始化列表,這就存在大量的重複,這種情況下可以將那些“賦值表現像初始化一樣好”的成員變量改用賦值操作來初始化,將這些賦值操作放在一個單獨的函數(比如private: void init())中,所有構造函數都來調用這個函數即可。


b.初始化次序1

  c++有着十分固定的“成員初始化次序”。base class更早於其derived class被初始化。


c.初始化次序2

  不同編譯單元內定義的non-local static對象的初始化次序。(深呼吸)

  函數內的static對象是local static對象,其他的都是non-local static對象。他們在程序結束時被自動銷燬,也就是他們的析構函數會在main()結束時被自動調用。

  所謂編譯單元是指產出單一目標文件的那些源碼,基本上是單一的源碼文件+頭文件(#include files)

  c++對“定義於不同編譯單元內的non-local static”對象的初始化次序並無明確定義。

  但是可以通過將non-local static對象轉換成local static對象來實現確定的初始化次序,因爲c++保證,函數內的local static對象會在“該函數被調用期間”“首次遇上改對象的定義式”時被初始化。這事單例模式(Singleton)常見的一個實現手法。

  額外1:Singleton模式是保證只有一個實例,它更關注結構,而MonoState是保證所有的實例都有相同的狀態,他側重於狀態。

  額外2:c++11要求local static對象的構造過程是線程安全的,所以單例模式在c++11下很簡單

class Singleton {
public:
  static Singleton& getInstance(){
    static Singleton instance;
    return instance;
  }
};

結論:

  a.爲內置對象進行手工初始化,因爲c++不保證初始化他們。

  b.構造函數最好使用初始化列表,而不是在構造函數體中賦值。初始化列表列出的成員變量,排列次序最好與他們在class中的聲明次序相同。

  c.爲免除“跨編譯單元的初始化次序”問題,請以local static對象替換non-local static對象。



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