我是新來C++風格的演員,並需要幫助理解下面的代碼如何工作(這是我寫的一些虛擬代碼來理解事物)。如何使用靜態轉換來管理共享對象的生命週期?
#include <iostream>
#include <memory>
class A {
public:
A() : a(1) {
std::cout << "Creating A\n";
}
~A() {
std::cout << "Destroying A\n";
}
int a;
};
class B : public A {
public:
B() : b(2) {
std::cout << "Creating B\n";
}
~B() {
std::cout << "Destroying B\n";
}
int b;
};
int main() {
std::shared_ptr<B> objectB(new B());
{
std::shared_ptr<A> (static_cast<A*>(objectB.get()));
std::cout << "End of inner scope\n";
}
std::cout << "End of outer scope\n";
}
它打印
Creating A
Creating B
Destroying A
End of inner scope
End of outer scope
Destroying B
Destroying A
我的理解:
Creating A -> B's ctor calls base class ctor
Creating B -> B's ctor
Destroying A -> ???
End of inner scope
End of outer scope
Destroying B -> B's dtor
Destroying A -> B's dtor calls base dtor
爲什麼我得到的第一個Destroying A
和究竟發生在這裏? A怎麼能被銷燬兩次?
這不是一個完整的答案,但你有兩個獨立的共享指針指向相同的東西。因此,在某些時候,將有多次嘗試釋放託管對象,這是未定義的行爲。另外,嘗試使用'std :: endl'而不是'\ n'來刷新stdout緩衝區。 – juanchopanza
我認爲你關於未定義行爲的觀點是有道理的,儘管我仍然試圖找到對此的參考。我知道'endl'可能有助於沖洗,但它不會改變順序。 – Lazer
@Lazer:它*是* UB多次刪除同一對象(可能搜索* double-delete *將更容易找到?),這就是您的代碼中發生的情況。此外,您應該在基類中使用虛擬析構函數,以確保在通過基類指針刪除派生對象時能夠得到適當的清理。 – syam