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を破壊する前に呼び出されていた可能性がある、ということですか?
「世界的なオブジェクトの短所はどのような順序で呼ばれていますか?
あなたの本当の疑問ですか?または、より関連性の高い質問です。「使用する前にグローバル(静的記憶域オブジェクト)が完全に初期化されていることをどのように保証するのですか?」 –
質問はこのように意図されていました。私はシングルトンのような仕組みを求めていませんでした。ありがとう! – ritter
グローバル変数よりも良い方法があります。関数内に静的な格納期間オブジェクトを持つことができます(参照を返すことができます)。最初の呼び出しで作成され、正しい順序で破棄されます。したがって、あなたがそれを使用するときには、正しく作成されることが保証されます**。 –