一般的にクラスをグローバルエリアで宣言することはあまりないと思うが、グローバル宣言を行うとき、実際に仮想関数のエリアおよびメンバー初期化がどのタイミングで行うかVisualC++のスタートアッププログラムをみて確認する(VisualC++6.0で確認しました)。
実行形式のスタートアッププログラムは、CRTEXE.Cになります。
開始プログラムは、WinMainCRTStartupになります(UNICODEは、wWinMainCRTStartup)
コンストラクターの初期化は、_initterm( __xi_a, __xi_z );で行われています。
(MFCのWinAppのInitInstanceメソッドは、上記もメソッドより後に実行されています)
このなかで、順次グローバル変数の初期化が実行されます(当然、Vテーブルの此処で設定されます)。
注意すべき点は、コンストラクタについては、当然初期化中においてもコードが動作する点です。
グローバル変数で定義されたクラスのメンバ変数は、コンストラクタ処理が実行されていない
間でも、メンバー変数を直接変更できることができるため、注意が必要です。
たとえば、Aのクラスで定義されているメンバ変数を使用するBのクラスを実行動作するものがあるとします
(どちらのクラスもグローバル変数で宣言されています)
この時、Aクラスのコンストラクタ実行前にBのクラスのコンストラクタが実行された場合、
Bのコンストラクター実行後、Aのコンストラクタ実行時にBクラスで必要なAクラスのメンバ変数を
初期化する可能性もでてきます。
このように、コンストラクタ内でコードを実行する際は、細心の注意を払う必要があります(デバッグがとても困難なため)。
ただ、Bのコンストラクタ前に、Aのコンストラクタが実行されれば、問題ないのですが、これはコンパイラーに
依存するため、問題がないとは言えません
