2016-11-26 98 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

相关问题