您好,登錄后才能下訂單哦!
C++規定對象的初始化動作發生在進入構造函數主體之前。(初始化列表比在構造函數體內初始化的效率高,以為在函數體內初始化會調用默認的構造函數)
編譯單元是指產出單一目標文件的那些源碼。
問題:
兩個源碼文件,每個文件中至少有一個non-local static對象(即該對象是全局的或者位于namespace作用域內,或在class內或file的作用域內被聲明為static)。如果某編譯單元內的non-local static對象的初始化用動作使用了另一個單元內的某個non-local static對象,在這個時候由于c++對定義在不同的編譯單元內的non-local static對象的初始化次序沒有明確的規定,所以用可能引發錯誤。
例子:
你寫的程序(一個編譯單元):
class FileSystem { public: … size-tnumDisk() const; … };
Extern FileSystem tfs;// 準備給別人用的對象
別人的程序(另一個編譯單元)
class Directory { Directory(params) { Size_tdisk=tfs.numDisks(); //使用第一個編譯單元的對象,假設在編譯這個文件之//前已經編譯了上一個文件那么沒錯,如果相反呢? } };
解決辦法:
將每個non-local static對象搬到自己專屬的函數內(也就是在函數內聲明為static)。這些函數返回一個引用指向它所含的對象。在調用的時候調用這些函數而不是直接調用對象。理由(c++保證,函數內的local static對象會在該函數調用期間首次遇上該對象的定義式時被初始化)
程序修改之后:
class FileSystem { public: … size-tnumDisk() const; … }; FileSystem& tfs() { static FileSystem fs; returnfs; } Class Directory { Directory(params) { Size_tdisk=tfs().numDisks(); //調用函數tfs() } }; Directory& tempDir() { Static Directory td; return td; }
任何一種non-conststatic對象不論他是local還是non-local,在多線程的環境下等待某事發生都會有麻煩,處理麻煩的做法是:在程序單線程啟動的階段手工調用引用返回的函數,這可以消除與初始化有關的競速形式。
總結:
一、對內置類型進行手工初始化(c++不保證初始化他們)。
二、構造函數最好使用成員初始列,而不要在構造函數內使用賦值操作,初始列的次序應該和class中的聲明次序相同。
三、為免除跨編譯單元的初始化問題,應該用local static對象替換non-local static對象。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。