c++多态(3) -- 虚析构函数

代码:  

enum class _ANIMALS_TYPE {CAT,DOG,ANIMAL_COUNT
};class Animal {
public:Animal(_ANIMALS_TYPE  type, int age,const char* name);~Animal();virtual void eat()const = 0;
private:_ANIMALS_TYPE  type;   // 动物类型int age;               // 动物年龄char* name = NULL;
};class CAT : public Animal {
public:CAT(_ANIMALS_TYPE  type, int age, const char* name,const char* love);~CAT();void eat()const override;
private:char* love = NULL;
};int main(void) {Animal* f = new CAT(_ANIMALS_TYPE::CAT, 5, "小猫", "小美");delete f;system("pause");return 0;
}Animal::Animal(_ANIMALS_TYPE type, int age, const char* name)
{this->type = type;this->age = age;if (this->name) {delete this->name;}int len = strlen(name) + 1;this->name = new char[len];strncpy(this->name, name, len);
}Animal::~Animal()
{cout << "调用Animal类的析构函数" << endl;// 如果name非空释放内存if (name) {delete name;}
}CAT::CAT(_ANIMALS_TYPE type, int age,const char*name,const char*love):Animal(type,age,name)
{if (this->love) {delete this->love;}int len = strlen(love) + 1;this->love = new char[len];strncpy(this->love, love, len);
}CAT::~CAT()
{cout << "调用CAT类的析构函数" << endl;if (love) {delete love;}
}void CAT::eat() const
{cout << "猫猫吃猫粮" << endl;
}

代码分析:   

1.    我们之前讲过,如果类内部有开辟空间,那么就需要在析构函数中释放空间,上面就是这种情况,我们在父类和子类中都开辟了内存,并且在析构函数中释放了内存。

2.   我们使用多态的原则(使用父类的指针指向子类的对象),代码中我们使用new开辟了一片子类内存,然后使用父类指针指向了子类的这片内存。 

3.  当开辟子类的内存时,会调用子类和父类的构造函数,那么就会给name和love属性开辟空间。 

4.  我们给父类指针开辟空间之后,使用结束就要释放这个指针。 因为在类中有开辟空间,释放是就需要调用析构函数,将申请的内存释放掉。 

 

5.  因为我们在申请内存的时候,父类的name和子类的love都开辟了内存,按理来说释放的时候都应该释放带哦,但是如图,释放时,只调用了父类的析构函数,也就是只释放了name。 

这种情况,明显有问题,子类申请的内存不释放,就会造成内存泄露的风险。 

原因: 

其实和之前的原因类似,就是虽然我们使用父类的指针指向了子类,但是指针是父类的,在释放内存的时候自然只会调用父类的析构函数。 

解决方法: 

和之前的解决方式一样,就是在父类析构函数前加上virtual,实现虚析构函数。至于为什么,那就和之前的虚函数是类似的了。 

 加上之后: 

  

这样在父类指针指向子类内存的时候,释放父类指针,不仅会调用父类的析构函数,也会调用子类的析构函数。 

代码技巧: 

为了防止上面的情况出现,我们建议如果一个类又子类就将析构函数加上virtual,如果有上面的情况,自然不会出问题,如果没有,加上也不影响。 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spring源码解读!底层原理进阶】【上】探寻Spring内部:BeanFactory和ApplicationContext实现原理揭秘✨

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;底层原理高级进阶》 &#x1f680…

解决CORS错误(Spring Boot)

记录一下错误&#xff0c;以博客的形式 前言 跨域&#xff08;Cross-Origin&#xff09;是指在Web开发中&#xff0c;当一个Web应用试图从一个源&#xff08;域名、协议、端口组合&#xff09;获取资源时&#xff0c;该请求的目标与当前页面的源不同。具体来说&#xff0c;当一…

SpringBoot之事务源码解析

首先事务是基于aop的&#xff0c;如果不了解aop的&#xff0c;建议先去看下我关于aop的文章: Spring之aop源码解析  先说结论&#xff0c;带着结论看源码。首先&#xff0c;在bean的生命周期中&#xff0c; 执行实例化前置增强&#xff0c;会加载所有切面并放入缓存&#xff0…

Django模板(三)

一、标签URL 返回与给定视图和可选参数相匹配的绝对路径引用(不含域名的 URL) {% url some-url-name v1 v2 %} 第一个参数是url模式名称,后面跟着的是参数,以空格分隔可以使用关键字: {% url some-url-name arg1=v1 arg2=v2 %}如果您想检索命名空间的URL,请指定完全限定…

最大子数组和[中等]

一、题目 给定一个长度为n的环形整数数组nums&#xff0c;返回nums的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c;nums[i]的下一个元素是nums[(i 1) % n]&#xff0c;nums[i]的前一个元素是nums[(i - 1 n) % n]。 子数…

AdaBoost算法

Boosting是一种集成学习方法&#xff0c;AdaBoost是Boosting算法中的一种具体实现。 Boosting方法的核心思想在于将多个弱分类器组合成一个强分类器。这些弱分类器通常是简单的模型&#xff0c;比如决策树&#xff0c;它们在训练过程中的错误会被后续的弱分类器所修正。Boosti…

Codeforces Round 923 (Div. 3)补题

Make it White&#xff08;Problem - A - Codeforces&#xff09; 题目大意&#xff1a;有一排格子&#xff0c;其中有黑色和白色两种&#xff0c;我们选择一个区间&#xff0c;将区间中的格子全部染成白色&#xff0c;只能选一次&#xff0c;问将这一排格子都染成白色&#x…

【doghead】VS2022 win11 安装配置WSL2 以编译linux端的cmake项目并运行1

Visual Studio 2022 在Windows上编译调试WSL2 CMake Linux工程 好像是我自己的vs2022的一个插件支持rust https://github.com/kitamstudios/rust-analyzer.vs/blob/master/PREREQUISITES.md Latest rustup (Rust Toolchain Installer). Install from here. Welcome to Rust!Th…

【性能最佳实践】跟着我们一起玩转查询模式与性能分析!

使用最新的驱动程序 MongoDB的官方驱动程序是由负责核心数据库开发的同一个专业团队打造的。这些驱动程序的更新通常比数据库本身更频繁&#xff0c;大概每几个月就会发布一次新版本。我们建议您尽可能使用最新版本的驱动程序&#xff0c;并在您使用的编程语言中安装可用的本地…

医学图像安全性概述

参考文献: Insights into security and privacy issues in smart healthcare systems based on medical images 下图左侧是医疗信息共享系统,右侧是计算机辅助诊疗策略: medical image sharing security (MISS)computer-aided diagnostic (CAD)CAD security (CADS)一般在信…

计算机毕业设计 | SSM超市进销存管理系统(附源码)

1&#xff0c;绪论 1.1 开发背景 世界上第一个购物中心诞生于美国纽约&#xff0c;外国人迈克尔库伦开设了第一家合作商店&#xff0c;为了更好地吸引大量客流量&#xff0c;迈克尔库伦精心设计了低价策略&#xff0c;通过大量进货把商品价格压低&#xff0c;通过商店一次性集…

Fink CDC数据同步(二)MySQL数据同步

1 开启binlog日志 2 数据准备 use bigdata; drop table if exists user;CREATE TABLE user(id INTEGER NOT NULL AUTO_INCREMENT,name VARCHAR(20) NOT NULL DEFAULT ,birth VARCHAR(20) NOT NULL DEFAULT ,gender VARCHAR(10) NOT NULL DEFAULT ,PRIMARY KEY(id) ); ALTER TA…