2017-02-22 16 views
5

スコットマイヤーズの書籍「Effective C++」と第4番目のアイテム:非ローカル静的オブジェクトは、使用前に初期化できません(静的な場合は、 "、静的な生活と)。参照を返す関数の内部に作成されたlocal-staticオブジェクトで置き換えると、そのオブジェクトは使用前に必ず初期化されます。C++ - ローカル以外の静的オブジェクトとローカル静的オブジェクト

私は常に定数を持つファイルを持っています。私はextern const int a;を.hppファイルに宣言し、それを.cppファイルで定義します。しかし、同じことが起こる可能性はありますか? aは初期化できません。か否か?組み込み型にも同じ規則が適用されますか?

+4

グローバルスコープ内の変数は常に*初期化されます。明示的に初期化されていない場合でも、システムはそれらを[* zero-initialize *](http://en.cppreference.com/w/cpp/language/zero_initialization)します。とにかく 'const'変数は明示的に初期化されなければなりません。 –

+0

http://stackoverflow.com/questions/1005685/c-static-initialization-order –

+0

こんにちは皆さん、ありがとうございます!私が見ている限り、組み込み型のグローバルオブジェクトの初期化は常にコンパイラによって処理されます。ローカルか非ローカルかは気にしないでください。 – Dusan

答えて

2

でも可能ですが、「ローカル静的」変数への参照を返すのはあまり良い考えではありません。この変数は(おそらく)局所的に宣言されてそのスコープを囲む関数に縮小したので、このようにスコープを拡大しようとするのはむしろ面倒です。あなたはそれをグローバル変数にして、std::call_onceのようなものを使用して、最初の使用時に一度だけ初期化されることを保証することができます。ローカル静的オブジェクトへの変更可能な参照を返すことは、関数がもはやリエントラントではない可能性があるため、スレッドセーフティの問題を引き起こします。

スタティックな記憶期間を持つPODタイプはゼロで初期化されることが保証されています。また、定数式で初期化することもできます。これにより、動的初期化が行われる前に初期化されます。いくつかの追加の洞察を提供するかもしれないa similar questionがあります。静的初期化に関する

0

問題はstatic initialization order fiascoとして知られている。要するに

、あなたが 別のソースファイル内に存在する2静的オブジェクトのxとyがあると、x.cppとy.cppを言います。 yオブジェクト(通常はyオブジェクトのコンストラクタ)の 初期化で がxオブジェクトのいくつかのメソッドを呼び出すとします。

定数を使用する別の翻訳単位を使用している場合は、プログラムが機能しない可能性があります。場合によっては、ファイル同士がリンクされた順序である場合もありますが、一部のプラットフォームではドキュメント内で定義することさえあります(私はSolarisがここにあると思います)。

The problem also applies to builtin types such as int.よくある質問の例は以下のとおりです。この例を実行する場合

#include <iostream> 
int f(); // forward declaration 
int g(); // forward declaration 
int x = f(); 
int y = g(); 
int f() 
{ 
    std::cout << "using 'y' (which is " << y << ")\n"; 
    return 3*y + 7; 
} 
int g() 
{ 
    std::cout << "initializing 'y'\n"; 
    return 5; 
} 

int main() { 
    std::cout << x << std::endl << y << std::endl; 
    return 0; 
} 

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

(0されている) 'Y'

を初期化する 'Y' を使用して

したがって、最初にゼロ初期化が行われ、次に定数初期化(?)が行われます。

ソリューションが Construct On First Use Idiomです:

まず利用イディオムで構築物の基本的な考え方は、関数内であなたの 静的オブジェクトをラップすることです。

静的ロカオブジェクトは、制御フローが宣言に初めて到達したときに構築されます。

関連する問題