標籤:
from: http://blog.csdn.net/classfactory/archive/2004/08/07/68202.aspx
在 C++ 中,同一個翻譯單位(.cpp檔案)裡的全域對象的初始化順序是先定義的對象先初始化(同時也後析構),但 C++ 標準並沒有規定不同翻譯單位間全域對象的初始化順序。按照這個分析,以下的代碼可能工作,也可能不工作(cout 是 C++ 用於輸出的全域對象,和我們自己的對象位於不同的翻譯單位):
class A {
A() {
cout << "A::A()";
}
~A() {
cout << "A::~A()";
}
};
A a;
OK,你會說這段代碼絕對運行正確,也就是說 cout 總是比我們的對象先初始化以及後析構。這是有原因的——雖然 C++ 標準並沒有明確規定,但各 C++ 編譯器都按照類似的方式實現了對全域對象初始化順序的控制,否則的話,C++ 庫就無法按照預期的方式工作了(如果不允許在全域物件建構函數中使用 cout 可能不少程式員會瘋掉)。
Visual C++ 提供了 #pragma init_seg 這樣一個編譯指令來控制一個翻譯單位中對象的初始化順序。開啟 Visual C++ 內建的 CRT 原始碼檔案 cout.cpp,你會發現如下的語句:
#pragma warning(disable: 4074)
#pragma init_seg(compiler)
_CRTIMP2 ostream cout(&fout);
通過使用 #pragma init_seg(compiler) 這個指令,在 cout.cpp 檔案中的所有對象都被放在 compiler 這個初始化組,這個組中的對象總是最先初始化和最後析構。當然,這個組是保留給微軟 C/C++ 運行庫使用的,我們不應該使用它。在我們自己的代碼裡,如果希望一些對象先於其他對象初始化,我們可以使用 #pragma init_seg(lib) 指令,放置在 lib 組的對象總是比 compiler 組的對象初始化晚,但要先於其他對象。#pragma init_seg 指令還有其他一些進階用法讓你進行更細緻的控制。
(註:編譯指令不屬於標準 C++ 的特性)
[百度空間] [轉] 在 Visual C++ 中控制全域對象的初始化順序