![](/img/trans.png)
[英]Do I still need to have a virtual destructor for my derived class in this situation?
[英]I have a virtual destructor and an array in my base class. How can I make it work?
例如:
class base
{
public:
base()
{
// allocate memory for basearray
}
virtual ~base()
{
// delete basearray
}
protected:
float* basearray;
};
class derived1 : public base
{
public:
derived1()
{
// allocate memory for derivedarray
}
~derived1()
{
// delete derived array
}
protect:
float* derivedarray;
};
void main()
{
derived1 d;
...
base* pb = &d;
...
// Delete base array?
}
我的基類中有一個虛擬析構函數和一個數組。 如果基類析構函數被派生類析構函數覆蓋,則基數組將不會被刪除。 有什么好的解決方案?
基類的析構函數被自動調用,派生類的析構函數運行之后。
當銷毀派生對象並且基部的析構函數是虛擬的時,兩個析構函數都將被調用。 您可以在這里確認: http : //ideone.com/RZamr
該順序將與構造函數的順序相反,即,在構造時,將首先調用base
的構造函數,然后再調用derived
。 首先銷毀時將調用derived
的析構函數,然后調用base
。
虛擬析構函數的工作方式不同於其他虛擬函數,因為基類的虛擬析構函數永遠不會被覆蓋。 相反,當子類提供自己的析構函數時,該子類析構函數將觸發,然后基類析構函數也會觸發。 使用“虛擬”是為了使您通過基類指針刪除派生類對象,C ++會根據對象的動態類型(子類)而不是靜態類型的指針(子類)來調用析構函數。超類)。 因此,您不需要在這里做任何特別的事情。 基類析構函數將照常工作。
希望這可以幫助!
覆蓋析構函數時,只要定義為“虛擬”,就仍會調用基類的析構函數。
因此,在此示例中:
class base
{
public:
base()
{
myarray = new float[100];
}
~base()
{
delete[] myarray;
}
private:
float* myarray;
}
class derived : public base
{
public:
derived()
{
}
~derived()
{
}
}
這不會刪除'myarray'並且會泄漏內存,因為基類析構函數被派生類析構函數隱藏。 然而:
class base
{
public:
base()
{
myarray = new float[100];
}
virtual ~base()
{
delete[] myarray;
}
private:
float* myarray;
}
class derived : public base
{
public:
derived()
{
}
~derived()
{
}
}
這將刪除陣列。
請記住,構造函數是從基類開始調用的,因此首先調用基類的構造函數,然后再調用派生類,而析構函數的調用順序相反,因此,派生類的析構函數先於基類調用。
沒問題 在派生類析構函數被調用之后立即調用基類析構函數。
僅有一種情況是不正確的:在指向基類析構函數不是虛擬的基類的指針上調用delete。
在所有具有在堆棧上創建的類的本地實例且函數或方法退出的情況下,即使由於異常,實例也會被正確地銷毀。
在所有情況下,如果類的實例是new
d,隨后又通過指向實例化的確切類的指針刪除了該實例,則該實例將被正確地銷毀。
當一個類的實例是new
d,但通過基類指針刪除時,只有在基類具有虛擬析構函數(聲明的virtual
本身或其自身的基具有虛擬析構函數)時,該實例才被正確地破壞。正確地破壞了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.