成员构造函数和析构函数调用的顺序

时间:2010-02-12 18:44:33

标签: c++

哦C ++大师,我寻求你的智慧。对我说说标准,告诉我C ++是否保证以下程序:

#include <iostream>
using namespace std;

struct A
{
    A() { cout << "A::A" << endl; }
    ~A() { cout << "A::~" << endl; }
};

struct B
{
    B() { cout << "B::B" << endl; }
    ~B() { cout << "B::~" << endl; }
};

struct C
{
    C() { cout << "C::C" << endl; }
    ~C() { cout << "C::~" << endl; }
};

struct Aggregate
{
    A a;
    B b;
    C c;
};

int main()
{
    Aggregate a;
    return 0;
}

将永远产生

A::A
B::B
C::C
C::~
B::~
A::~

换句话说,成员是否保证按声明顺序初始化并以相反的顺序销毁?

4 个答案:

答案 0 :(得分:123)

  

换句话说,成员是否保证按声明顺序初始化并以相反的顺序销毁?

两者都是。见12.6.2

  

6 初始化应在   以下顺序:

     
      
  • 首先,仅限于   派生最多的构造函数   类如下所述,虚拟基础   课程应在课程中初始化   命令它们出现在深度优先   从左到右遍历   有向无环图的基数   类,“从左到右”是   基类的出现顺序   派生类中的名称   基本符列表。

  •   
  • 然后,直接   基类应初始化为   声明顺序,因为它们出现在   base-specifier-list(不管是什么   mem-initializers的顺序)。

  •   
  • 然后,非静态数据成员应该是   按照他们的顺序初始化   在类定义中声明   (再次无论顺序如何   MEM-初始化)。

  •   
  • 最后,   构造函数的复合语句   身体被执行。 [注意:   声明命令是强制性的   确保基础和成员子对象   以相反的顺序被摧毁   初始化。 - 尾注]

  •   

答案 1 :(得分:28)

是的,他们是(非静态成员)。初始化(构造)见12.6.2 / 5,销毁见12.4 / 6.

答案 2 :(得分:9)

是的,标准保证对象按照创建它们的相反顺序被破坏。原因是一个对象可能使用另一个对象,因此依赖于它。考虑:

struct A { };

struct B {
 A &a;
 B(A& a) : a(a) { }
};

int main() {
    A a;
    B b(a);
}

如果在a之前b要销毁,则b将保留无效的成员引用。通过按照创建它们的相反顺序破坏对象,我们保证正确的破坏。

答案 3 :(得分:5)

是的,是的。对于成员变量,破坏的顺序总是与构造顺序相反。