3 回答

TA貢獻1887條經驗 獲得超5個贊
該標準保證兩件事 - 在同一翻譯單元中定義的對象(通常表示.cpp文件)按其定義(而不是聲明)的順序初始化:
3.6.2
具有靜態存儲持續時間(basic.stc.static)的對象的存儲應在任何其他初始化發生之前進行零初始化(dcl.init)。使用常量表達式進行零初始化和初始化統稱為靜態初始化; 所有其他初始化是動態初始化。具有使用常量表達式(expr.const)初始化的靜態存儲持續時間的POD類型(basic.types)的對象應在任何動態初始化發生之前初始化。在同一翻譯單元的命名空間范圍內定義并動態初始化的靜態存儲持續時間的對象應按其定義出現在翻譯單元中的順序進行初始化。
另一個有保證的事情是,在使用來自此翻譯單元的任何對象或函數之前,將從翻譯單元初始化靜態對象:
無論是否在main的第一個語句之前完成命名空間作用域對象的動態初始化(dcl.init,class.static,class.ctor,class.expl.init),它都是實現定義的。如果初始化延遲到main的第一個語句之后的某個時間點,則它應該在第一次使用與要初始化的對象相同的轉換單元中定義的任何函數或對象之前發生。
我保證沒有其他任何東西(特別是在不同翻譯單元中定義的對象的初始化順序是實現定義的)。

TA貢獻1807條經驗 獲得超9個贊
它們在程序開始之前(即在main
輸入之前)初始化。
當單個CPP文件中存在兩個或多個(靜態數據的)定義時,它們將按照在文件中定義它們的順序進行初始化(文件中先前/后面定義的那個在下一個之前初始化)一個是)。
當在多個CPP文件中存在兩個或多個(靜態數據的)定義時,處理CPP文件的順序是未定義/特定于實現的。如果全局變量的構造函數(在程序啟動之前調用)引用另一個可能尚未構造的CPP文件中定義的全局變量,則會出現此問題。但是,Meyers的Effective C ++(標題為確保全局對象在使用前已初始化)的第 47項確實描述了一種解決方法......
在頭文件中定義一個靜態變量(它是靜態的,所以你可以有多個實例而不需要鏈接器抱怨)
讓該變量的構造函數調用您需要的任何東西(特別是構造在頭文件中聲明的全局單例)
...它說的是一種可以在某些系統頭文件中使用的技術,例如確保cin
在靜態變量的構造函數使用它之前初始化全局變量。

TA貢獻1866條經驗 獲得超5個贊
您在編輯中的最終結論是正確的。但問題是班級自己。更容易說我的代碼將具有不引用其他全局數據/類靜態成員的類靜態成員,但是一旦采用這種方法,事情很快就會出錯。我發現在實踐中有一種方法是不使用類靜態數據成員而是使用類靜態包裝器方法。然后,這些方法可以將靜態對象保存在自身內。例如
TypeX* Class2::getClass1Instance(){
static TypeX obj1;
return &obj1;}
注意:早先的答案是:
另一個有保證的事情是,在使用來自此翻譯單元的任何對象或函數之前,將完成從翻譯單元初始化靜態對象
這不完全正確,這里錯誤地推斷出標準。如果在輸入main之前調用翻譯單元中的函數,則這可能不成立。
- 3 回答
- 0 關注
- 982 瀏覽
添加回答
舉報