析构函数的virtual在子类

Posted windmissing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了析构函数的virtual在子类相关的知识,希望对你有一定的参考价值。

运行结果是什么?

father *pf = new father();
delete pf;
father *ps = new son();
delete ps;
son *ps1 = new son();
delete ps1;
son *pss = new sonson();
delete pss;
father *pss1 = new sonson();
delete pss1;

运行结果

delete father()
delete father()
delete son()
delete father()
delete sonson()
delete son()
delete father()
delete father()

解释与结论

virtual关键字在父类virtual关键字在子类已经说明virtual关键字在父类的情况能够正常地进行多态。因此这里仅把关注点放在virtual关键字在子类的情况。

由于析构函数与普通函数略有不同,把virtual关键字在子类的情况对析构函数再测一遍。结论与virtual关键字在子类类似。

id指针名指针的类型实际的类型运行结果解释
1pffatherfatherdelete father()
2psfathersondelete father()实际调用的是指针的类型(father)的析构函数,说明没有多态
3ps1sonsondelete son()
delete father()
调用了son(),son()又调用了~father() ,由编译器完成。
4psssonsonsondelete sonson()
delete son()
delete father()
实际调用的是对象的类型(sonson)的函数,说明有多态的效果。sonson()又调用了son()以及~father(),由编译器完成。
5pss1fathersonsondelete father()实际调用的是指针的类型(father)的析构函数,说明没有多态

结论:

  1. 如果virtual只写在派生类的析构函数中,而没有写在基类中的析构函数中,则不会有多态的效果。有可能只析构基类部分而不析构派生类部分,造成内存泄漏。

  2. 如果在某一层的派生类中加了virtual标签,那么从这一层开始以后的每一层,这个函数都会有多态的效果。

其它测试

virtual关键字在父类

virtual关键字在子类

间接调用虚函数

完整代码

#include <iostream>
using namespace std;

class father

public:
  ~father()
  
    cout<<"delete father()"<<endl;
  
;

class son : public father

public:
  virtual ~son()
  
    cout<<"delete son()"<<endl;
  
;

class sonson : public son

public:
  ~sonson()
  
    cout<<"delete sonson()"<<endl;
  
;

int main()

  father *pf = new father();
  delete pf;
  father *ps = new son();
  delete ps;
  son *ps1 = new son();
  delete ps1;
  son *pss = new sonson();
  delete pss;
  father *pss1 = new sonson();
  delete pss1;
  return 0;


以上是关于析构函数的virtual在子类的主要内容,如果未能解决你的问题,请参考以下文章

条款09:绝不在构造和析构过程中调用virtual函数

Virtual destruct(虚析构函数)

一文读懂C#中的抽象类抽象方法virtual虚函数override重写函数及父类子类构造函数和析构函数的执行顺序

改善程序与设计的55个具体做法 day3

多态中的虚析构函数

类中的析构函数是否是虚函数