一,产生原因:
1,自动调用基类部分的析构函数对基类的设计有重要影响。删除指向动态分配对象的指针时,需要运行析构函数在释放对象的内存之前清除对象。处理继承层次中的对象时,指针的静态类型可能与被删除对象的动态类型不同,可能会删除实际指向派生类对象的基类类型指针。
2,如果删除基类指针,则需要运行基类析构函数并清除基类的成员,如果对象实际是派生类型的,则没有定义该行为。要保证运行适当的析构函数,基类中的析构函数必须为虚函数:
#include<iostream>
#include<string>
using namespace std;
class base
{
public:
base(const string &book="",double sales_price=0.0)
:isbn(book), price(sales_price) { };
virtual double net_price(std::size_t n) const
{
return n * price;
}
virtual ~base();
private:
string isbn;
protected:
double price;
};
base::~base()
{
}
3,如果析构函数为虚函数,那么通过指针调用时,运行哪个析构函数将因指针,所指对象类型的不同而不同:
base *itemP = new base; // same static and dynamic type
delete itemP; // ok: destructor for Item_base called
itemP = new child; // ok: static and dynamic types differ
delete itemP; // ok: destructor for Bulk_item called
像其他虚函数一样,析构函数的虚函数性质都将继承。因此,如果层次中根类的析构函数为虚函数,则派生类析构函数也将是虚函数,无论派生类显式定义析构函数还是使用合成析构函数,派生类析构函数都是虚函数。即使析构函数没有工作要做,继承层次的根类也应该定义一个虚析构函数。