2011-08-28 10 views
2

C++でグローバルオブジェクトのコンストラクタをどのように呼び出すのですか?グローバルなコンストラクタはどのような順序で呼び出されますか

この質問は、一部のコンシューマのメモリニーズを管理するメモリプールのコンテキストで発生します。私は、ちょうどヒープ関数を使用している一部のコンシューマをグローバルな名前空間で定義するかなり大きなソースコードを提示されました。コンシューマの名前空間を変更せずにメモリプールを追加する必要があります。そこで、プールクラスとグローバル名前空間に定義を追加し、各コンシューマクラスを変更してクラス "thePool"のインスタンスからメモリを取得しました。残念なことに、実行の終わりに、すべてのグローバルデストラクタを呼び出すとき、私は素敵なセグメンテーションを取得します。 gdbのバックトレースは、pool :: freeへのブランチがsegfaultを生成することを示しています。これは私にとって奇妙に聞こえる。しかし、私はそれをグローバルな名前空間に存在する非常に単純なプール/コンシューマの例に煮詰めました。残念ながら、これはsegfaultを再現しません - プールのデストラクタは消費者のすべてのデストラクタの後に呼び出されます。これは純粋な運、またはg ++ 4.5のよく教育された推測ですか?

ここで煮詰め例:

#include<iostream> 

using namespace std; 


struct pool { 
    pool() { 
    cout << "pool::pool" << endl; 
    } 
    ~pool() { 
    cout << "pool::~pool" << endl; 
    } 
    void get() { 
    cout << "pool::get" << endl; 
    } 
    void free() { 
    cout << "pool::free" << endl; 
    } 
}; 

pool thePool; 


struct consumer { 
    ~consumer() { 
    cout << "consumer::~consumer" << endl; 
    thePool.free(); 
    } 
    consumer() { 
    cout << "consumer::consumer" << endl; 
    thePool.get(); 
    } 
}; 



consumer a,b; 

int main() { 
} 

出力は次のようになります。

pool::pool 
consumer::consumer 
pool::get 
consumer::consumer 
pool::get 
consumer::~consumer 
pool::free 
consumer::~consumer 
pool::free 
pool::~pool 

ナイス!ちょうど私がそれを望んでいた。純粋な幸運?私はプールのdtorが消費者aまたはbを破壊する前に呼び出されていた可能性がある、ということですか?

「世界的なオブジェクトの短所はどのような順序で呼ばれていますか?

+0

あなたの本当の疑問ですか?または、より関連性の高い質問です。「使用する前にグローバル(静的記憶域オブジェクト)が完全に初期化されていることをどのように保証するのですか?」 –

+0

質問はこのように意図されていました。私はシングルトンのような仕組みを求めていませんでした。ありがとう! – ritter

+0

グローバル変数よりも良い方法があります。関数内に静的な格納期間オブジェクトを持つことができます(参照を返すことができます)。最初の呼び出しで作成され、正しい順序で破棄されます。したがって、あなたがそれを使用するときには、正しく作成されることが保証されます**。 –

答えて

7

グローバル変数は、宣言されている順序で初期化されます。そのコンストラクタは、初期化されたのと同じ順序で呼び出されます。これは1つの内で当てはまるtranslation unit。しかし、複数の翻訳単位にわたる初期化順序は、言語仕様によって定義されていません。

デストラクタは、いつものように初期化の逆の順序で呼び出されます。

+0

いいです、妥当と思われます。デストラクタはどうですか?厳密に逆の順序で定義されていますか? – ritter

+0

「古い」C++ 2003スタンドがそれについて語ったことを見つけようとしましたが、グローバルスコープで静的な記憶期間を持つオブジェクトのctors、dtorsの実行順序については何も見つかりません – bruziuz

4

翻訳単位間では定義されていませんが、宣言の順番は異なります。

関連する問題