簡體   English   中英

C ++-析構函數調用順序

[英]C++ - Destructor call order

我有以下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;
    }

我了解除析構函數調用外,控制流中的所有內容。 這是沒有析構函數的控制流:

  1. 創建對象B

  2. 調用構造函數B分別調用a,aa,aaa

2.1 for a,呼叫A(int x)

2.2 for aa,呼叫A(int x)

2.3對於aaa,調用A()

  1. 從B控制器本體顯示B

現在,步驟4.是調用析構函數B,我知道。

我不知道為A調用析構函數的順序是什么。分別是a,aa,aaa還是aaa,aa,a?

提前致謝。

成員對象按照與它們構造相反的順序銷毀。 請注意,您不會通過更改構造函數的初始化列表中的順序來影響此順序。 該順序完全由您在struct / class定義中聲明它們的順序確定。

我不知道為A調用析構函數的順序是什么。分別是a,aa,aaa還是aaa,aa,a?

因此,后一種情況正在發生。

一切看起來都很好。 它以堆棧方式構造-分解(先進先出):

#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; }
     ^

這花了很長時間才找到,但是根據n4659(ISO C ++ 17草案):

15.6.2初始化基礎和成員

段落(13.3)

然后,非靜態數據成員按照它們在類定義中聲明的順序進行初始化(同樣,無論mem-initializer的順序如何)。

[注意:聲明順序是強制執行的,以確保以相反的初始化順序銷毀基礎和成員子對象。 —尾注]

在這里, mem-initializers是構造函數定義中冒號后面的列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM