2011-09-24 41 views
5

我有一個向量的頭,像這樣:全局向量在調用之間清空本身?

extern std::vector<Foo> g_vector; 

在相關的CPP文件我有這樣的:

std::vector<Foo> g_vector; 

我也有一類Bar,並在它的構造也將增加有些東西g_vector,像這樣:

Bar::Bar(/* stuff */) 
{ 
    // do things 
    std::cout << g_vector.size() << std::endl; 
    g_vector.push_back(somefoo); 
    std::cout << g_vector.size() << std::endl; 
} 

如果我宣佈一個Bar一個函數裏,像一個理智人,它似乎工作正常。但是,如果我想在函數之外聲明Bar,會發生奇怪的事情。例如,我在MyFile1.cpp和MyFile2.cpp中聲明瞭Bar,並且由於我在Bar中的cout語句,我可以看到Foo被推入向量中,但是當下一個Bar運行其構造函數時,向量的大小爲0再次。換句話說,我的輸出是

0 
1 
0 
1 

什麼給?爲了加倍確保,我還嘗試打印出&g_vector以確保它實際上是push_back進入正確的向量,並且地址都匹配。對於它的價值,這些東西進入矢量的順序並不重要。我不關心初始化順序或任何東西。

+1

你有什麼理由相信你的'g_vector'會在你的靜態'Bar'實例之前被構造? – Gabe

回答

6

不知道問題到底是什麼,但我猜想以下模式可以幫助解決它:定義全局變量的訪問器並將其分配爲靜態函數變量,如下所示。

在頭文件:

std::vector<Foo> &getGlobalVector(); 

在cpp文件:

std::vector<Foo> &getGlobalVector() 
{ 
    static std::vector<Foo> s_vector; 
    return s_vector; 
} 

這種模式是由安德烈Alexandrescu的的 「通用單」 實施現代C++的設計靈感。

我已經養成了系統地使用這種模式的習慣,只要我在保持現有應用程序的同時落在現有全局變量上(或者在極少數情況下我實際上選擇使用自己的應用程序),並且它可能有助於消除在所述應用程序中幾個難以重現的錯誤。

無論如何,這應該真的有助於避免任何多重初始化或初始化順序相關問題。

6

未定義全局值初始化的順序。

在這裏閱讀關於static initialization fiasco

當您在函數中聲明Bar - g_vector將在之前被初始化,因爲它承諾在程序運行之前進行初始化。如果Bar是一個全局變量 - 那麼你有一個問題。