当我们delete一个动态分配的对象的指针时将执行析构函数。如果指针指向继承体系中的某个类型,则有可能出现指针的静态类型与被删除的动态类型不相符合的情况。例如,如果我们要delete一个parent*(父类指针)类型的对象,则该指针可能指向了一个son(子类)类型的对象。如果这样的话,编译器就必须清楚地知道它应该执行的是parent的析构函数,还是son的析构函数。
1 //假设parent没有虚析构函数,son是它的子类 2 parent* getsomething();//此函数返回一个指针,指针指向son派生类的动态分配对象 3 4 5 parent* ptk=getsomething(); 6 delete ptk;//此行为未定义,编译器不知道调用谁的析构函数
我们通过在基类中将析构函数定义为虚函数以确保执行正确的析构函数版本:
1 class parent 2 { 3 virtual ~parent(){} 4 }
和其它虚函数一样,析构函数的虚属性也会被继承。因此,无论parent的派生类使用的析构函数是自己的还是编译器生成的析构函数,都将是虚析构函数。只要基类的析构函数是虚函数,就能确保我们delete基类指针时将运行正确的析构函数版本:
1 parent* item=new parent;//静态类型与动态类型一致 2 delete item;//调用parent的析构函数 3 4 parent* item1=new son;//静态类型与动态类型不一致 5 delete item1;//调用son的析构函数
如果基类的析构函数不是虚函数,则delete一个指向派生类对象的基类指针将产生未定义的结果。
什么时候需要将类的析构函数声明为虚析构函数:
一个类内含有虚函数会使对象的体积增加,而且代码移植性变差。当一个类不作为基类的时候,通常没必要将其虚构函数声明未virtual;如果类带有任何virtual函数,那么该类就应该拥有一个virtual析构函数,因为该类的设计目的一般是多态用途;如果不是为了多态用途而设计的基类,则也不需要virtual析构函数。
原文:https://www.cnblogs.com/cs0915/p/12747131.html