[英]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;
}
我了解除析構函數調用外,控制流中的所有內容。 這是沒有析構函數的控制流:
創建對象B
調用構造函數B分別調用a,aa,aaa
2.1 for a,呼叫A(int x)
2.2 for aa,呼叫A(int x)
2.3對於aaa,調用A()
現在,步驟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.