[英]The Virtual Destructor in C++
我確實已經解決了現有的問題,但是我仍然真的需要回答這個問題,才能真正知道我是否理解這項權利。
通常,我們唯一定義自己的析構函數的時間是在內存中動態分配某些內容時。
但是,我們仍然需要實現自己的析構函數(即使堆上沒有動態分配任何東西),只是為了將其命名為虛擬的(如果堆上沒有任何分配,它就可以是純虛擬的),基類地址(指針/引用)以訪問派生類的對象。 (我的推論)無條件地正確嗎?
因為如果有:
Base* p = new Derived;
現在要刪除p,即空閑內存,我們必須將析構函數聲明為virtual並執行:
delete p;
正確?
Base* p = new Derived;
現在要刪除p,即空閑內存,我們必須將析構函數聲明為virtual並執行:
delete p;
正確?
是
作為該問題的答案(還指出delete是否與指向基類的指針一起使用?
是的,只有當基類析構函數是虛擬的時,它才能工作
如果析構函數的實現很簡單,則可以執行
virtual ~Base() = default;
此外,派生類型應使用override
。
virtual ~Derived() override = default;
^^^1^^^ ^^^2^^^^
// 1: Optional because the base destructor is virtual
// 2: The compiler will verify the base destructor is virtual
是。 最好假定將存在具有析構函數的子類,這些析構函數需要運行,因此虛擬析構函數需要存在於Base
。 同樣,即使在沒有任何析構函數代碼的情況下,在銷毀時也會發生其他事情。
class Derived : public Base {
MyMember m;
}
如果在Base
上沒有虛擬析構函數,則當您多態刪除(將其刪除為Base*
)時,將永遠不會調用m
的析構函數。
如果計划允許任意子類的Base
子類化,則需要Base
具有虛擬析構函數,以便安全地刪除這些子類。
不建議為Base
考慮一個非虛擬的析構函數,因為您將需要保證所有子類不僅沒有析構函數,而且它們都沒有帶有析構函數的成員 ……這意味着在對象中沒有stl容器或其他任何東西。 其他開發人員很容易錯過這種奇怪的要求,因此您應該只在Base
有一個虛擬析構函數。
您只需要將基類的析構函數設為虛擬。 派生類可以顯式定義析構函數,也可以使用由構造函數定義的隱式一個。
struct Base
{
virtual ~Base() {}
};
struct Derived1 : public Base
{
// Explicitly defined destructor.
// Use of virtual is optional.
~Derived () {}
std::vector<std::string>> data;
};
struct Derived2 : public Base
{
// Use the compiler defined destructor
std::vector<int>> data;
};
用法:
Base* p = new Derived1;
...
delete p; // OK
p = new Derived2;
...
delete p; // OK
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.