zoukankan      html  css  js  c++  java
  • 把类的析构函数写成虚函数的用意

    原文链接

    Cpp代码 
    #include <iostream.h>
    class Base 
    { 
    public: 
    Base() { mPtr = new int; } 
    ~Base() { delete mPtr; cout<<"Base::Destruction"<<endl;} 
    private: 
      int* mPtr; 
    } ;
    
    class Derived : public Base 
    { 
    public: 
      Derived() { mDerived = new long; } 
      ~Derived() { delete mDerived; cout<<"Derived::Destruction"<<endl;} 
    private: 
      long* mDerived; 
    } ;
    
    void main() 
    { 
      Base* p = new Derived; 
      delete p; 
    } 
    输出结果只有:Base::Destruction
    以上代码会产生内存泄露,因为new出来的是Derived类资源,采用一个基类的指针来接收,析构的时候,编译器因为只是知道这个指针是基类的,所以只将基类部分的内存析构了,而不会析构子类的,就造成了内存泄露,如果将基类的析构函数改成虚函数,就可以避免这种情况,因为虚函数是后绑定,其实就是在虚函数列表中,析构函数将基类的析构函数用实际对象的一组析构函数替换掉了,也就是先执行子类的虚函数再执行父类的虚函数,这样子类的内存析构了,父类的内存也释放了,就不会产生内存泄露。
     
    应该为
    #include <iostream.h>
    class Base 
    { 
    public: 
    Base() { mPtr = new int; } 
    virtual ~Base() { delete mPtr; cout<<"Base::Destruction"<<endl;} 
    private: 
      int* mPtr; 
    } ;
    
    class Derived : public Base 
    { 
    public: 
      Derived() { mDerived = new long; } 
      ~Derived() { delete mDerived; cout<<"Derived::Destruction"<<endl;} 
    private: 
      long* mDerived; 
    } ;
    
    void main() 
    { 
      Base* p = new Derived; 
      delete p; 
    } 
     
    注:
    1.析构函数其实是一个函数,不论子类还是父类,虽然可能看起来名字不一样。而且析构函数执行过程都是执行子类再到父类。
    2.多态的时候一定要将析构函数写成虚函数,防止内存泄露,各个子类维护自己内部数据释放。
     
    virtual 是实现多态的基础
    它使得具体的函数跳转从编译时推迟到运行时然而构造函数的调用是编译器期间就决定的,因此它不能为虚
  • 相关阅读:
    从零开始通过webhooks实现前端自动化
    使用rem配置PC端自适应大屏
    Nuxt内导航栏的两种实现方式
    VueX中直接修改数据报错,修改一维数组,二维数组,报错的原因
    在mpvue或者Vue中使用VUEX
    小程序框架MpVue踩坑日记(二)
    小程序mpvue中动态切换echarts图表
    小程序踩坑之不同屏幕下动态改变translate值
    Koa2+MySQL+VUE+ElementIUI搭建简单的后台管理小系统
    小程序框架MpVue踩坑日记(一)
  • 原文地址:https://www.cnblogs.com/wangkangluo1/p/2496589.html
Copyright © 2011-2022 走看看