2013-11-22 26 views
0

假設我有以下兩個變量,都是靜態初始化的,而且它們以不同的編譯單元居住。是否有任何保證靜態初始化不會覆蓋顯式初始化的值?

Foo.cc

Foo foo; 

Bar.cc

​​

假設,通常bar靜態foo後初始化。

如果foo的構造函數被寫入寫bar的價值,是有一個機會的bar隨後的靜態初始化將覆蓋由foo?

,被寫的值,假設Bar有第二個構造這需要一個字符串,併爲foo的構造是這樣的:

Foo::Foo() { 
    bar = Bar("Hello World"); 
    /// do other stuff to make a Foo 
} 

是否有任何機會,對於bar靜態初始化將後運行並覆蓋由foo的構造函數寫的bar的值?

+0

使用'const的酒吧巴;'也許?? –

+0

當bar靜態初始化時,它不會檢查它是否已經被初始化,它只會做它的事情。所以是的,這有一個機會,它與{你的一天/一小時多麼不方便,你是多麼的醉心,你有多累,如果你現在接電話,你的家人會被逐出家園的可能性有多大} 。 – kfsone

+0

[相關](http://stackoverflow.com/a/18140733/179910)。 –

回答

0

正如Scott Meyers表示:

[...]在不同的翻譯單位定義非局部靜態對象的初始化的相對順序是不確定的。 [...]

和:

幸運的是,小的設計改動完全消除這個問題。所有必須做的事情是將每個非本地靜態對象移動到它自己的函數中,在那裏它被聲明爲靜態的。這些函數返回對它們包含的對象的引用。客戶然後調用函數而不是引用對象。換句話說,非本地靜態對象被替換爲本地靜態對象。 (設計模式愛好者將識別此作爲共同執行Singleton模式。)

作爲該工作的一個例子可以看着:http://www.parashift.com/c++-faq/static-init-order-on-first-use-members.html

+0

我試過這種方法,它加了0。7 ms到之前在高度延遲敏感應用程序中的5 ms延遲。 – merlin2011

+0

我的猜測是,用靜態封裝函數可能相當於每次調用條件時強制分支。 – merlin2011

+0

@ merlin2011您可以避免這種解決方案,將防護裝置放入敏感對象以確保初始化順序。例如,如果foo取決於酒吧,則在酒吧裏放置一個警戒,告訴它是否被初始化。在foo初始化時。測試這個警衛。如果它沒有被初始化。初始化吧,否則,只是初始化foo。 – Amadeus

1

是的,動態初始化(這是當你的靜態構造函數被調用時發生的情況)可能以任何順序發生。

如果靜態對象需要相互依賴,最好的做法是根據需要動態分配它們並保護初始化,使其僅發生一次,類似於singleton模式。