C++中定义虚析构函数的原因
如果类中有虚函数,一般将该类的析构函数定义为虚函数。
在下面的例子中,没有将析构函数定义为虚函数:
#include "iostream"
using namespace std;
class Parent
{
public:
Parent(int a = 0)
{
cout << "Parent()" << endl;
this->a = a;
}
//virtual ~Parent()
~Parent()
{
cout<<"~Parent()"<<endl;
}
private:
int a;
};
class Child : public Parent
{
public:
Child(int b = 0)
{
cout<<"Child()"<<endl;
this->b = b;
}
~Child()
{
cout<<"~Child()"<<endl;
}
private:
int b ;
};
//在父类中声明虚析构函数的原因
//通过父类指针,把所有的子类析构函数都执行一遍。。。
void howtoDel(Parent *pbase)
{
delete pbase;
}
int main()
{
Child *pc1 = new Child();
howtoDel(pc1);
cout << "***********************" << endl;
Parent *pp1 = new Parent;
howtoDel(pp1);
return 0;
}
输出:
Parent()
Child()
~Parent()
Parent()
~Parent()
可以看到执行howtoDel(pc1);析构子类对象的时候,仅仅调用了父类的析构函数,而没有根据传入的子类对象就调用子类的析构函数。
将析构函数定义为虚函数:
#include "iostream"
using namespace std;
class Parent
{
public:
Parent(int a = 0)
{
cout << "Parent()" << endl;
this->a = a;
}
virtual ~Parent()
{
cout<<"~Parent()"<<endl;
}
private:
int a;
};
class Child : public Parent
{
public:
Child(int b = 0)
{
cout<<"Child()"<<endl;
this->b = b;
}
~Child()
{
cout<<"~Child()"<<endl;
}
private:
int b ;
};
//在父类中声明虚析构函数的原因
//通过父类指针,把所有的子类析构函数都执行一遍。。。
void howtoDel(Parent *pbase)
{
delete pbase;
}
int main()
{
Child *pc1 = new Child();
howtoDel(pc1);
cout << "***********************" << endl;
Parent *pp1 = new Parent;
howtoDel(pp1);
return 0;
}
输出:
Parent()
Child()
~Child()
~Parent()
Parent()
~Parent()
可以看到执行howtoDel(pc1);析构子类对象的时候,调用了父类的析构函数,也根据传入的子类对象调用子类的析构函数。(还可以看到在子类对象中构造函数和析构函数执行的顺序是相反的)
在父类中声明虚析构函数的原因:通过父类指针,把所有的子类析构函数都执行一遍。这也是多态现象。

本文通过两个实例对比展示了在C++中为什么需要将基类的析构函数声明为虚函数。当通过基类指针删除派生类对象时,若基类析构函数不是虚函数,则只会调用基类的析构函数;而将其声明为虚函数,则会正确地调用派生类的析构函数。
275

被折叠的 条评论
为什么被折叠?



