问:虚析构函数的作用是什么?
答:用基类指针删除派生类的对象时,让派生类的析构函数可以被调用;
答案涉及到几个重要信息:
第一:基类指针,也就是说声明的指针必须是基类或者是还有派生类的派生类,或者说一定不是最底层派生类;
第二:派生类的对象,生成的对象一定要是派生类的对象,如果new的对象本身就是声明的类,那也没必要用虚析构,浪费空间;
第三:派生类析构函数,只要满足前面两个条件信息,基类的析构函数(确切来说是派生类对象的声明类)一定要用虚析构函数;
虚析构函数,在基类和派生类之间,通过基类new一个派生类对象,在后面析构的时候,如果基类的析构函数不为虚析构,将不会执行派生类的析构函数,如下:
#define CLASS(ID) class ID \
{ \
public: \
ID(){ cout << #ID " constructor \n"; } \
~ID(){ cout << #ID " deconsturctor \n"; } \
}
CLASS(Base1);
CLASS(Memb1);
CLASS(Memb2);
CLASS(Memb3);
CLASS(Memb4);
class Derived1 :public Base1
{
public:
Derived1(){ cout << "Derived1 constructor \n"; }
~Derived1(){ cout << "Derived1 deconstructor \n"; }
static const int s;
protected:
private:
Memb1 m1;
Memb2 m2;
};
class Derived2 :public Derived1
{
public:
Derived2(){ cout << "Derived2 constructor \n"; }
~Derived2(){ cout << "Derived2 deconstructor \n"; }
Memb3 m3;
Memb4 m4;
};
int _tmain(int argc, _TCHAR* argv[])
{
Base1 *pd2 = new Derived2;
cout << sizeof(Derived1) << endl;
cout << sizeof(Derived2) << endl;
delete pd2;
getchar();
return 0;
}
1.如果Base1析构前面不加关键词virtual,执行结果如下:
结论:并不是每一个类的析构函数都要写成虚析构函数,因为这会给类增加储存空间,只有当一个类被用来做为基类,且实例化为派生类的时候才需要写成虚函数;
也就是说如果用derived1 *pd = new derived1 ,这个时候就不需要写虚构函数,但如果new derived2的话就必须将derived1的析构函数写成虚析构,不然derived2的析构函数将不会运行,但不管是第一种情况还是第二种情况,base1的析构函数都会运行;