虚析构函数的作用

news2024/11/15 22:34:17

类的析构函数是为了释放内存资源,析构函数不被调用的话就会造成内存泄漏。

虚析构函数

定义为虚析构函数是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。

但并不是要把所有类的析构函数都写成虚函数。只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。

#include <iostream>
using namespace std;
class Base
{
public:
    Base(string data) : m_data(data){ cout << "Base(string data)"<< endl;}
     ~Base(){ cout << "Base:: ~Base" << endl; }
    void show(){ cout << m_data << endl; }
    string GetData(){ return m_data; }
private:
    string m_data;
};

class Demo : public Base
{
public:
    Demo(int id, string data) : m_id(id), Base(data){ cout << "Demo(int id, string data)"<< endl;}
     ~Demo(){ cout << "Demo::~Demo" << endl; }
    void display(){ cout << m_id << "  " << GetData() << endl; }
private:
    int m_id;
};

int main()
{
    Demo* DDemo = new Demo(1, "hello"); //子类指针指向子类
    cout << "delete 子类指针"<< endl;
    delete DDemo;
    cout << "-----------------------"<< endl;
    Base* BBase = new Demo(2, "zhou");  //父类指针指向子类
    cout << "delete 父类指针" << endl;
    delete BBase;

    system("pause");
    return 0;
}

可以看出只释放了父类Base 的内存空间,势必会造成内存泄露。

从运行结果中可以的到:

-当子类指针指向子类时,析构函数会先调用子类析构在调用父类析构,释放所有内存。

- 但父类指针指向子类时,只会调用父类析构函数,子类析构函数不被调用,会造成内存泄漏。

所以我们才需要虚析构函数,将父类的析构函数定义为虚析构函数,那么父类指针会先调用子类析构,在调用父类析构,是内存得到释放。

改动代码在基类的析构函数前面添加virtual ,子类 的析构函数前面virtual 可写可不写

#include <iostream>
using namespace std;
class Base
{
public:
    Base(string data) : m_data(data){ cout << "Base(string data)"<< endl;}
    virtual ~Base(){ cout << "Base:: ~Base" << endl; }
    void show(){ cout << m_data << endl; }
    string GetData(){ return m_data; }
private:
    string m_data;
};

class Demo : public Base
{
public:
    Demo(int id, string data) : m_id(id), Base(data){ cout << "Demo(int id, string data)"<< endl;}
    virtual ~Demo(){ cout << "Demo::~Demo" << endl; }   //  这个virtual 可写可不写
    void display(){ cout << m_id << "  " << GetData() << endl; }
private:
    int m_id;
};

int main()
{
    Demo* DDemo = new Demo(1, "hello"); //子类指针指向子类
    cout << "delete 子类指针"<< endl;
    delete DDemo;
    cout << "-----------------------"<< endl;
    Base* BBase = new Demo(2, "zhou");  //父类指针指向子类
    cout << "delete 父类指针" << endl;
    delete BBase;

    system("pause");
    return 0;
}

从运行结构可以看出:

- 将父类定义为虚析构函数后,当定义一直父类指针指向子类时,在delete时可以调用子类和父类的析构函数,释放所有的内存,防止内存泄漏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息论复习—卷积码

目录 卷积码的基本概念&#xff1a; 卷积码与分组码的不同特点&#xff1a; 卷积码的构造与表示方法&#xff1a; 卷积码编码器的结构&#xff1a; 卷积码(3,1,3): 卷积码的卷积关系: 卷积码的生成矩阵: 卷积码的多项式: 系统码结构的卷积码: 卷积码的监督矩阵: 卷积…

Pipenv使用指南:轻量级虚拟环境管理工具详解

前言 终于能够挤出一点时间来总结最近学到的一些技术知识点了&#xff0c;博主这两周被居家隔离-集中隔离-居家隔离来回折腾&#xff0c;现在终于是得到解放能够空出的时间来写写博客了&#xff0c;但是项目又催的紧&#xff0c;写博文的时间还是有限&#xff0c;这周我会尽量…

正则语言的性质

正则语言的性质 一、正则语言的性质 1.正则语言的泵引理 设LLL是正则语言&#xff0c;则存在与LLL相关的常数nnn满足&#xff1a;对于任何LLL中的串www&#xff0c;如果∣w∣≥n|w|\geq n∣w∣≥n&#xff0c;则我们就能把www打断为三个串wxyzwxyzwxyz使得&#xff1a; y̸ϵ…

2011年专业408

文章目录0 结果1 题目2 思路2.1 思路1&#xff08;暴力解&#xff1a;排序&#xff09;2.2 思路2&#xff08;较优解&#xff1a;归并合并数组&#xff09;2.3 思路3&#xff08;较优解&#xff1a;数组指针后移&#xff09;2.4 思路4&#xff08;最优解&#xff1a;两个数组的…

ARM BTI指令介绍

目录 一、JOP 二、BTI 三、启用BTI 四、BTI是怎么实现的 一、JOP JOP&#xff08;Jump-oriented programming&#xff09;类似于ROP&#xff08;Return-Oriented Programming&#xff09;。在 ROP 攻击中&#xff0c;会扫描出useful gadgets&#xff08;易被攻击的一段代码…

【数据结构】顺序队列的原理及实现

1.什么是队列 队列是一种比较特殊的线性表&#xff0c;特殊就在于它只允许在表的前端来进行删除&#xff0c;在表的后端来进行插入&#xff0c;队列它是一种操作受限制的线性表。插入的一端称为队尾&#xff0c;删除的一端称为队头&#xff0c;队列里没有元素就称它为空队列。…

快速使用代码编辑工具vim+ctags+cscope快捷使用itop3568开发板

当以上配置全部完成后&#xff0c;每当拿到新的工程代码&#xff0c;进入相关代码目录&#xff0c;利用 vim ./命令打 开当前目录&#xff0c; 然后 crtl 生成插件所需文件&#xff0c;最后使用命令:qa!退出 vim。此步只需进行一 次。 在此目录中打开任意代码文件或任意子目录…

jdk8新特性-日期时间

1、介绍 日期时间类在Java开发中是必不可少的&#xff0c;前后端如何传递时间参数、数据库的时间在Java中对应什么类型、Java中时间转换的各种方式有哪些&#xff1f; 2、Date类 Date类是JDK1.0时期推出来的第一代时间类&#xff0c;位于java.util包下&#xff0c;是最常用的…

unctf easy_serialize反序列化字符逃逸

&#xfeff;ctf题目平台&#xff1a;UNCTF - HACKING 4 FUN。web题难度适中 easy_serialize 题目源码&#xff1a; <?php include "function.php"; $action $_POST[action]; $name $_POST[name]; $pass $_POST[pass]; $email $_POST[email]; ​ function …

南京小米java面经(一面)

目录1.java支持多继承吗2.线程的生命周期3.线程和进程的区别4.单例模式有几种5.写一下双重锁的单例6.jvm有哪些区域7.jvm哪些区域是线程共享的&#xff0c;哪些是线程私有的8.gc中判断对象可回收的方式有哪些9.gc垃圾回收算法有哪些10.哪些对象可以作为gc root11.gc中的引用计数…

软件设计师教程(四)程序设计语言基础知识

软件设计师教程 软件设计师教程&#xff08;一&#xff09;计算机系统知识-计算机系统基础知识 软件设计师教程&#xff08;二&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;三&#xff09;计算机系统知识-计算机体系结构 程序设计语言知识软件设计师…

工资管理系统

一、系统简介 工资管理涉及企业管理的多个方面&#xff0c;如员工基本信息、员工在职离岗、员工考勤、员工加班等等。根据这些信息&#xff0c;在每个月的固定时间&#xff0c;生成全体员工的月工资&#xff0c;部门月工资以及全厂月工资。对于月工资&#xff0c;能够实现按照员…

机器学习【西瓜书/南瓜书】--- 第五章 神经网络

1.神经元模型 1.1 M-P神经元模型 输出函数&#xff1a; 其中θ为阈值&#xff0c; ω i为第i个神经元的连接权重&#xff0c; xi为来自第i个神经元的输入。 1.2 激活函数 阶跃函数&#xff1a; 理论上我们使用阶跃函数。将输入值映射为输出值为0/1&#xff0c;显然1为神经元…

Windows下编译安装OpenCASCADE

OpenCASCADE (以下简称OCC)是一套开源的几何建模系统&#xff0c;提供了曲面、实体等建模方式&#xff0c;已经广泛应用在CAD、CAE、CAM等软件开发。 OpenCASCADE官网已经提供OpenCASCADE的编译安装方法&#xff0c;本文结合实操过程&#xff0c;简述其过程。 零、环境 操作系…

Databend v0.9.0 版本发布

各位社区小伙伴们&#xff0c;历经数月开发&#xff0c;Databend 于 2023 年 1 月 13 日迎来了 v0.9.0 版本的正式发布&#xff01; 这次新版本是 Databend 迈向 1.0 版本的最后一个大版本&#xff0c;也是迄今为止我们对核心代码重构幅度最大的一个版本&#xff01;相较于 v0…

C++ string容器,cha*

目录 1.string基本概念 2.string构造函数,char* 3.string赋值操作 4.string字符串拼接,append 5.string查找和替换,find,replace 6.string字符串比较,compare 7.string字符存取[].at&#xff0c;取&#xff0c;修改单个字符&#xff0c;size返回字符串长度 8.string插入和…

数学建模学习笔记(13)分类模型

分类模型分类问题的基本概念逻辑斯蒂回归&#xff08;Logistic&#xff09;Fisher线性判别分析多分类问题的SPSS求解分类问题的基本概念 分类问题概述&#xff1a;对于给定的一个对象&#xff0c;根据其特征将其划分到多个已给定的类别中的一个。 二分类和多分类&#xff1a;…

题目:两数之和

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录描述描述 方式1:暴力遍历 public static int[] twoSum(int[] nums, int target) {int i 0;int j 1;int[] result new int[2];for(int m i;m<nums.length-1;m){…

13.3nm粒径水溶性Cds/CdTe-PAA-P4VP/BSA的制备方法

13.3nm粒径水溶性Cds/CdTe-PAA-P4VP/BSA的制备方法今天小编分享量子点偶联聚合物&#xff0c;一起看看吧&#xff1a;Cds/CdTe-PAA-P4VP/BSA的制备过程&#xff1a;称取86.5mgCdCl2于三口瓶中&#xff0c;加入295mL二次水&#xff08;考虑到在调pH值时会增加溶液的体积&#xf…

(14)工业界推荐系统-小红书推荐场景及内部实践【重排】

&#xff08;1&#xff09;工业界推荐系统-小红书推荐场景及内部实践【业务指标、链路、ItemCF】 &#xff08;2&#xff09;工业界推荐系统-小红书推荐场景及内部实践【UserCF、离线特征处理】 &#xff08;3&#xff09;工业界推荐系统-小红书推荐场景及内部实践【矩阵补充、…