2016-11-26 101 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()然後拋出一個異常,構造函數被中止,並且b或B :: a都不被認爲是構造的。

爲什麼b第一次沒有初始化?

回答

3

每次控制通過變量定義時,都會嘗試初始化具有靜態存儲持續時間的塊範圍變量,直到成功爲止。

從[stmt.dcl]/4:

具有靜態存儲的持續時間(3.7.1)或線程存儲 持續時間(3.7.2)的塊範圍可變的動態初始化執行第一時間控制通過其聲明;這樣的變量在其初始化完成時被初始化爲 。 如果通過拋出異常退出初始化,則初始化未完成,因此下一次控制進入聲明時將再次嘗試初始化。

B型罐當然,如果其任何成員的結構拋出異常不完整的的目的的結構。

+0

並以破壞靜態變量的順序它不會有任何影響? – Adib

+0

@Adib:我不明白 - 影響什麼?靜態變量按照其構造的相反順序銷燬(但當然這隻有在建築實際發生時纔有意義)。 –

+0

是的,我完全想知道這一點,因爲靜態變量在異常之前沒有構建,所以它不會改變破壞順序。對 ? – Adib

相關問題