2016-11-26 9 views
1

静的ローカル変数はいつ初期化されますか? コンストラクタで例外がスローされた場合、そのオブジェクトは構築されていると見なされますか?デストラクタは呼ばれますか?静的ローカル変数が初期化される前に例外が発生した場合はどうなりますか?

休閑コードを検討:

#include <iostream> 
#include <exception> 

int x = 0; 

class A { 
public: 
    A() { 
    std::cout << 'a'; 
    if (x++ == 0) { 
     throw std::exception(); 
    } 
    } 
    ~A() { std::cout << 'A'; } 
}; 

class B { 
public: 
    B() { std::cout << 'b'; } 
    ~B() { std::cout << 'B'; } 
    A a; 
}; 

void foo() { static B b; } 

int main() { 
    try { 
    foo(); 
    } 
    catch (std::exception &) { 
    std::cout << 'c'; 
    foo(); 
    } 
} 

出力:acabBA

初めてのfoo()が呼び出され、Bは初期化しようとしています。そのコンストラクタが呼び出され、最初にすべてのメンバ変数が構築されます。これは、A :: A()が呼び出され、aを出力することを意味します。 A :: A()は例外をスローし、コンストラクタは中断され、bまたはB :: aのどちらも実際に構築されているとはみなされません。

なぜ初めてbが初期化されなかったのですか?

答えて

3

静的ストレージ期間を持つブロックスコープ変数の初期化は、制御が成功するまで制御が変数定義をパススルーするたびに試行されます。 【stmt.dcl]/4から

静的ストレージ期間(3.7.1)またはスレッドストレージ 期間(3.7.2)を有するブロックスコープ変数の動的な初期化が最初に実行されます時間制御はその宣言を通る。そのような変数は、その初期化の完了時に初期化されたと考えられます( )。 例外をスローすることによって初期化が終了した場合、 の初期化は完了していないため、次回コントロールが宣言を入力したときに再試行されます。

そのメンバーのいずれかの建設が例外をスローした場合、もちろんのタイプB缶のオブジェクトの建設が完了していません。

+0

と静的変数の破壊の順序では何の影響もありませんか? – Adib

+0

@Adib:わかりません - 何が効果?静的変数は、構築の逆の順序で破棄されます(もちろん、実際に構築が行われた場合にのみ関連します)。 –

+0

はい、私はこれを知りたかったのですが、静的変数は例外の前に構築されていなかったので、破壊の順序は変わりませんでした。右 ? – Adib

関連する問題