あなたが持っている被付与者:
- グローバル名前空間内のすべての静的非ローカルオブジェクトは、main()の前に構築されます
- 別の名前空間内のすべての静的な非ローカルオブジェクトは、その名前空間内の関数/メソッドが使用される前に構築されます(したがって、コンパイラーがそれらを遅延評価する可能性があります[ただし、この動作は期待しないでください])。
- 翻訳ユニット内のすべての静的な非ローカルオブジェクトは、宣言の順序で作成されます。
- 翻訳ユニット間の順序については何も定義されていません。
- すべての静的な非ローカルオブジェクトは、作成の逆の順序で破棄されます。(これには、静的関数変数(最初の使用時に遅延して作成される)が含まれます。
相互に依存関係のあるグローバルがある場合は、次の2つのオプションがあります。
- それらを同じ翻訳単位に入れます。
- それらを、最初の使用時に取得および構築された静的関数変数に変換します。
例1:グローバルAのコンストラクターはグローバルログを使用します
class AType
{ AType() { log.report("A Constructed");}};
LogType log;
AType A;
// Or
Class AType()
{ AType() { getLog().report("A Constructed");}};
LogType& getLog()
{
static LogType log;
return log;
}
// Define A anywhere;
例グローバルBのデストラクタはグローバルログを使用します
ここでは、オブジェクトログがオブジェクトBの前に破棄されないことを許可する必要があります。これは、ログがBの前に完全に構築される必要があることを意味します(破棄ルールの逆の順序が適用されるため)。ここでも同じ手法を使用できます。それらを同じ変換単位に配置するか、関数を使用してログを取得します。
class BType
{ ~BType() { log.report("B Destroyed");}};
LogType log;
BType B; // B constructed after log (so B will be destroyed first)
// Or
Class BType()
{ BType() { getLog();}
/*
* If log is used in the destructor then it must not be destroyed before B
* This means it must be constructed before B
* (reverse order destruction guarantees that it will then be destroyed after B)
*
* To achieve this just call the getLog() function in the constructor.
* This means that 'log' will be fully constructed before this object.
* This means it will be destroyed after and thus safe to use in the destructor.
*/
~BType() { getLog().report("B Destroyed");}
};
LogType& getLog()
{
static LogType log;
return log;
}
// Define B anywhere;