簡體   English   中英

為什么銷毀順序和構造順序一樣,都是static object (C++)?

[英]Why is the order of destruction same as order of construction, with static object (C++)?

代碼是:

#include <iostream>
using namespace std;

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

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

int main()
{
    B b;
    static A a;
    return 0;
}

output 是:

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

非靜態object b的scope和static object a的scope在main() function的最后結束。

問題:為什么構造函數的順序與析構函數的順序相同?

Static 局部變量將在程序退出時銷毀。

塊作用域 static 變量的析構函數在程序退出時調用,但前提是初始化成功。

所以b將在main()結束時首先被銷毀, a將在這之后被銷毀。

對於初始化,

在控件第一次通過它們的聲明時被初始化

所以b將首先在main()中初始化,然后a被初始化。

因為它們的壽命不同。 A被聲明為函數局部變量 static。

Object 由自動函數局部變量的聲明創建,其生命周期在使用該 object 之前開始,並以包含該聲明的最嵌套代碼塊(大括號塊)結束。 在您的情況下,這是 function main()主體。

由 static 函數局部變量聲明創建的 Object 在執行流進入包含該聲明的最嵌套代碼塊之后並且在使用該 object 之前開始存在。它獲得了進程范圍的生命周期(停止存在於std::atexit() ),這發生在 function main()將退出之后。

因此,在這種特殊情況下,它們是按聲明順序創建的,但A稍后會被銷毀。 如果您的 function 被調用兩次,您會看到B將被創建兩次,但A只會被創建一次。 如果函數的流程以某種方式省略聲明,通過if()語句或通過提前返回,它們的創建順序將改變或兩者都可以省略。

它是特定於實現的細節,但通常通過調用位於std::atexit實現下的庫 function,添加與指針值綁定的析構函數的地址,以與全局對象的破壞相同的方式實現函數局部靜態的破壞object 本身,但執行可能與用戶調用std::atexit的結果並發(或可能不是)。

作為對現有答案的補充,讓我們采用更現象學的方法。 考慮對您的示例進行一些小改動:

void foo() {
    B b;
    static A a;
}

int main() {
    foo();
    foo();
}

我假設你知道a只被初始化一次,在第二次調用時我們得到完全相同的 object a ,因為它被聲明為static 因此,它不能在第一次調用foo期間或之后立即銷毀。 output 的預期第一部分是

B::B    // first call to foo()
A::A
B::~
B::B    // second call to foo()
        // no second call to A::A !
B::~    

a只能在你的程序終止時被銷毀,否則你不能在再次調用 function 時“重用”它(這就是為什么我必須修改示例,你不能調用main )。 正如其他答案所詳細解釋的那樣,這發生在main返回之后。 因此 output 的最后一行將是

 A::~

暫無
暫無

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

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