![](/img/trans.png)
[英]Is the destructor of a derived class virtual by-default if the base class destructor is virtual?
[英]Is a derived class destructor definition required if base class destructor is virtual?
我正在嘗試以下示例:
class base // base class
{
public:
std::list<base*> values;
base(){}
void initialize(base *b) {
values.push_front(b);
}
virtual ~base()
{
values.clear();
cout<<"base called"<<endl;
}
};
class derived : public base // derived class
{
public:
~derived(){
cout<<"derived called"<<endl;
}
};
int main()
{
derived *d = new derived;
base *b = new base;
b->initialize(static_cast<base *>(d)); /* filling list */
delete b;
return 0;
}
Q.1)為什么不調用派生類的析構函數,因為在基類析構函數中我正在執行values.clear()
?
Q.2)如果基類析構函數是虛擬的,是否需要派生類析構函數定義?
Q1。 因為您沒有刪除derived
類型的對象。 你只做delete b;
,刪除base
。 你也應該叫delete d;
。
此外,您應指定負責內存管理的對象。 您的設計容易出錯。 你最好使用智能指針來防止歧義。 此外,為了按照您的預期行事,析構函數應該是:
virtual ~base()
{
for ( int i = 0 ; i < values.size() ; i++ )
delete values[i];
values.clear();
cout<<"base called"<<endl;
}
當然,使用這種方法,它將是未定義的行為,調用delete d;
在你的main
。
Q2。 不,這個定義不是必需的。
為什么沒有調用派生類的析構函數,因為在基類析構函數中我正在執行
values.clear();
values.clear()
從該列表中刪除所有指針。 它不會刪除被指向的對象; 這將是非常危險的,因為該列表無法知道它是否對其生命周期負責,或者它們是否僅用於引用其他地方管理的對象。
如果您希望列表擁有對象,則必須在刪除它們時自行刪除它們,或者存儲智能指針,例如std::unique_ptr<base>
。 如果您的編譯器不支持新的智能指針,那么您可能會發現Boost的指針容器庫很有用。
是否需要派生類析構函數定義。 如果基類析構函數是虛擬的。
只有在派生類中需要清理的東西時才需要它。 如果沒有什么可以做的話,就沒有必要定義一個空的。
為什么你認為應該調用派生類的析構函數? 您只刪除base,它是基類的實例。
不需要析構函數的定義 - 您可以省略它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.