C - 击质器呼叫订单

C++ - Destructor call order

本文关键字:呼叫      更新时间:2023-10-16

我有以下C 代码:

#include <iostream>
struct A 
{
    A() { std::cout << "A" << ++x; }
    A(int x) : A() { std::cout << x; }
    ~A() { std::cout << "D"; }
    static int x;
};
int A::x = 0;
struct B 
{
    A a, aa, aaa;
    B() : aa(1), a(2) { std::cout << "B" << std::endl; }
    ~B() { std::cout << "B" << A::x; }
};
B beta;
    int main()
    {
        return 0;
    }

我了解控制流中的所有内容,除了destructor调用。这是没有破坏者的控制流程:

  1. 创建对象b

  2. 呼叫构造函数b分别致电A,AA,AAA

2.1对于A,请致电A(int x)

2.2对于AA,请致电A(int x)

2.3对于AAA,请致电A()

  1. b c-tor主体显示b

现在。4。步骤是致电destructor b,我知道。

我不知道的是呼叫A的命令的顺序。分别是a,aa,aaa或aaa,aa,一个?

预先感谢。

成员对象被构造的反向顺序销毁。请注意,您不会通过更改构造函数初始化列表中的顺序来影响此顺序。该顺序仅由您在struct/class定义中声明的顺序确定。

我不知道的是呼叫A的命令的顺序是什么。

因此,后一种情况正在发生。

一切看起来都很好。它构造destructs堆栈(首先/最后一个):

#include <iostream>
struct A 
{
    A() { name="untitled"; std::cout << name <<" constructor" << std::endl; }
    A(std::string name):name(name) { std::cout << name <<" constructor" << std::endl; }
    ~A() { std::cout << name <<" destructor" << std::endl; }
    std::string name;
};
struct B 
{
    A a, aa, aaa;
    B() : aa("aa"), a("a") { std::cout << "B constructor" << std::endl; }
    ~B() { std::cout << "B destructor" << std::endl; }
};
B beta;
int main()
{
    return 0;
}

结果:

a constructor
aa constructor
untitled constructor
B constructor
B destructor
untitled destructor
aa destructor
a destructor

该订单保证吗?是


如果打开所有警告,您会看到以下警告:

 g++ -Wall -Wreorder main.cpp 

main.cpp: In constructor ‘B::B()’:
main.cpp:12:10: warning: ‘B::aa’ will be initialized after [-Wreorder]
     A a, aa, aaa;
          ^
main.cpp:12:7: warning:   ‘A B::a’ [-Wreorder]
     A a, aa, aaa;
       ^
main.cpp:13:5: warning:   when initialized here [-Wreorder]
     B() : aa("aa"), a("a") { std::cout << "B constructor" << std::endl; }
     ^

这需要 forever 找到,但根据N4659(ISO C 17草稿):

15.6.2初始化基础和成员

段(13.3)

然后,非静态数据成员按在类定义中声明的顺序初始化(无论MEM-Initializers的顺序如何)。

[注意:命令声明令确保在初始化的反向顺序。 - 终注]

在这里, mem-initializers是构造函数定义中的结肠的列表。