我一直在用我無法真正理解的析構函數調用順序掙扎。C++ 11 shared_ptr對象的本地靜態成員變量銷燬順序
假設我們有如下定義:
#include <memory>
#include <iostream>
class DummyClass {
std::string name;
public:
DummyClass(std::string name) : name(name) { std::cout << "DummyClass(" << name << ")" << std::endl; }
~DummyClass() { std::cout << "~DummyClass(" << name << ")" << std::endl; }
};
class TestClass {
private:
static DummyClass dummy;
static DummyClass& objects() {
static DummyClass dummy("inner");
return dummy;
}
public:
TestClass() {
std::cout << "TestClass" << std::endl;
std::cout << "TestClass Objects is: " << &objects() << std::endl;
}
virtual ~TestClass() {
std::cout << "~TestClass Objects is: " << &objects() << std::endl;
std::cout << "~TestClass" << std::endl;
}
};
DummyClass TestClass::dummy("outer");
現在,如果我實例化TestClass
如下:
TestClass *mTest = nullptr;
int main() {
mTest = new TestClass(); delete mTest;
return 0;
}
獲得的輸出是一個我希望:
DummyClass(outer)
TestClass
DummyClass(inner)
TestClass Objects is: 0x....
~TestClass Objects is: 0x....
~TestClass
~DummyClass(inner)
~DummyClass(outer)
但是,現在,如果我使用mTest的shared_ptr,如:
std::shared_ptr<TestClass> mTest;
int main() {
mTest = std::make_shared<TestClass>();
return 0;
}
產生的輸出是:
DummyClass(outer)
TestClass
DummyClass(inner)
TestClass Objects is: 0x....
~DummyClass(inner)
~TestClass Objects is: 0x....
~TestClass
~DummyClass(outer)
有人可以解釋爲什麼在的TestClass對象的析構函數結束之前被破壞DummyClass內部對象,在該特定情況? 我發現gcc 5.2.0使用-std = gnu ++ 11和clang 3.8.0與-std = C++ 11一致的行爲,但找不到引用此示例的任何特定文檔。
編輯:澄清:上述所有代碼都按照所提供的順序寫入相同的翻譯單元(* .cpp文件)。這是一個簡單的使用情況,我只有一個頭部類定義,它必須包含一個指向派生類對象的靜態列表this
指針。這些指針是通過ctor添加的,並在達到dtor時被刪除。銷燬最後一個對象時觸發該問題。該列表保存在一個靜態方法裏面並通過它來訪問,以實現標題只有的目標。
是定義'DummyClass的TestClass ::假(「外」);'和'的std :: shared_ptr的 MTEST;'在同一個翻譯單元(* .cpp文件),或者是不同的?如果同一個,哪一個是第一個? –
aschepler
在本例中,所有內容都位於同一翻譯單元中。順序如前所述,所以'DummyClass TestClass :: dummy(「outer」);'出現在'std :: shared_ptr之前 mTest;' –