C++分析如何用虚析构与纯虚析构处理内存泄漏

 更新时间:2022年08月24日 16:32:58   作者:_拾贰_  
虚析构和纯虚析构共性:可以解决父类指针释放子类对象,都需要有具体的函数实现;虚析构和纯虚析构区别:如果是纯虚析构,该类属于抽象类,无法实例化对象

一、问题引入

使用多态时,如果有一些子类的成员开辟在堆区,那么在父类执行完毕释放后,没有办法去释放子类的内存,这样会导致内存的泄漏。如下代码段。

如果没有堆区的数据,可以不写虚析构或纯虚析构。

#include <iostream>
#include <string>
using namespace std;
class Animal{
  public:
    Animal(){
        cout<<"Animal-构造"<<endl;
    }
      ~Animal(){
        cout<<"Animal-析构"<<endl;
    }
    virtual void Run()=0;  //纯虚函数无需实现,只需声明
};
class Cat:public Animal{
  public:
  string *s_name;
  Cat(string name){
      s_name = new string(name);//在堆区创建内存
      cout<<"Cat-构造"<<endl;
  }
  void Run()
  {
      cout<<*s_name<<"->"<<"Cat-Run"<<endl;
  }
  ~Cat(){
      cout<<"Cat-析构"<<endl;
      if(s_name!=NULL){
          delete s_name;
          s_name=NULL;
      }
  }
};
int main()
{
    Animal *a;
    a = new Cat("Tom");
    a->Run();
    delete a;   //父类指针析构的时候,不会调用子类析构函数
    return 0;
}

运行结果:

结果可以看到都有父类和子类的构造,虽然在主函数中delete 父类,但最终只有父类的析构函数,此时子类在堆区创建的s_name并没有得到释放,导致内存泄漏。

以上的问题我们引入虚析构和纯虚析构来解决——父类指针释放子类对象时不干净的问题

二、利用虚析构解决

虚析构只需要在析构函数前加关键字 virrtual 即可,再观察结果,可以看到父类和子类的都执行了析构函数,而子类中在堆区创建的数据也被释放干净,这是最终的结果!

   virtual ~Animal(){
        cout<<"Animal析构"<<endl;
    }

三、利用纯虚析构解决

纯虚析构格式如下,和纯虚函数有点类似,但需要有具体的声明和具体的实现。纯虚析构需要在类外实现.

class Animal{
  public:
    Animal(){
        cout<<"Animal-构造"<<endl;
    }
    //虚析构
     /*virtual ~Animal(){
        cout<<"Animal析构"<<endl;
    }*/
    //纯虚析构
    virtual ~Animal()=0;
    virtual void Run()=0;  //纯虚函数无需实现,只需声明
};
//需要有声明,也需要有实现
Animal::~Animal(){
    cout<<"纯虚析构"<<endl;
}

结果如下,和虚析构有相同的作用

四、总结

虚析构和纯虚析构

相同点: 都可以解决父类指针释放子类对象,都需要有具体的实现

不同点: 纯虚析构属于抽象类,无法实例化对象

到此这篇关于C++分析如何用虚析构与纯虚析构处理内存泄漏的文章就介绍到这了,更多相关C++内存泄漏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++超详细讲解模板的使用

    C++超详细讲解模板的使用

    这篇文章主要介绍了C++中模板(Template)的详解及其作用介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • 一文带你分清C++的定义,声明和初始化

    一文带你分清C++的定义,声明和初始化

    这篇文章主要为大家详细介绍了C++的定义,声明,初始化,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • VS+QT编译环境中字符乱码问题解决方法

    VS+QT编译环境中字符乱码问题解决方法

    编码就是把⼀个字符编码成二进制码存起来的方式,而解码就是把这个二进制码按照原本编码的规则还原成原来的字符,这篇文章主要介绍了VS+QT编译环境中字符乱码问题详解,需要的朋友可以参考下
    2024-01-01
  • 一篇文章带你了解C语言浮点数之间的比较规则

    一篇文章带你了解C语言浮点数之间的比较规则

    这篇文章主要介绍了魔性的float浮点数精度问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • C++中的运算符和运算符优先级总结

    C++中的运算符和运算符优先级总结

    这篇文章主要介绍了C++中的运算符和运算符优先级总结,主要整理了算术、关系、逻辑、位和赋值运算符的用法,需要的朋友可以参考下
    2016-05-05
  • C++二维数组螺旋加密信息

    C++二维数组螺旋加密信息

    大家好,本篇文章主要讲的是C++二维数组螺旋加密信息,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • C/C++实现捕获所有信号的示例详解

    C/C++实现捕获所有信号的示例详解

    Linux的信号机制大部分情况下用不到,但是由于大部分信号的默认处理是终止进程,不正确处理会惹麻烦,所以我们来看看如何使用C/C++实现捕获所有信号吧
    2024-03-03
  • OpenCV利用高斯模糊实现简单的磨皮美颜效果

    OpenCV利用高斯模糊实现简单的磨皮美颜效果

    这篇文章主要介绍了通过OpenCV中的高斯模糊以及双边模糊来实现一个简单的磨皮美颜效果,文中的讲解很详细,感兴趣的同学可以学习一下
    2021-12-12
  • C++顺序表实现图书管理系统

    C++顺序表实现图书管理系统

    这篇文章主要为大家详细介绍了C++顺序表实现图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C语言实例真题讲解数据结构中单向环形链表

    C语言实例真题讲解数据结构中单向环形链表

    链表可以说是一种最为基础的数据结构了,而单向链表更是基础中的基础。链表是由一组元素以特定的顺序组合或链接在一起的,不同元素之间在逻辑上相邻,但是在物理上并不一定相邻。在维护一组数据集合时,就可以使用链表,这一点和数组很相似
    2022-04-04

最新评论