C++ 遗失的子类析构函数

Echats-wordcloud 文字云图的踩坑点【Unknown series wordCloud】 一直都是报 【ECharts Unknown series wordCloud】这玩意可能要刷脸,祝你好运吧~ 阅读详情

这篇博文所讲的是多态中的一个小BUG

我们知道,在构造函数中调用了new给指针分配内存,那么就要在析构函数中释放掉该内存;那么,如果在多态实验中 基类指针指向子类对象时会怎么样呢?

代码:

#include <iostream>
#include <string.h>

class Father {
public:
	Father(const char *addr = "中国") {
		std::cout << "调用了Father类的构造函数" << std::endl;
		this->addr = new char[strlen(addr)+1];
		strcpy_s(this->addr, strlen(addr)+1, addr);
	}

	~Father() {
		std::cout << "调用了Fahter类的析构函数" << std::endl;
		if (addr) {
			delete addr;
			addr = NULL;
		}
	}

private:
	char *addr;
};

class Son : public Father {
public:
	Son(const char *game = "吃鸡", const char *addr = "中国") : Father(addr) {
		std::cout << "调用了Son类的构造函数" << std::endl;
		this->game = new char[strlen(game)+1];
		strcpy_s(this->game, strlen(game)+1, game);
	}

	~Son() {
		std::cout << "调用了Son类的析构函数" << std::endl;
		if (game) {
			delete game;
			game = NULL;
		}
	}

private:
	char *game;
};
int main(void) {
	std::cout << "---示例一---" << std::endl;
	Father *father = new Father();
	delete father;

	std::cout << "---示例二---" << std::endl;
	Son *son = new Son();
	delete son;

	std::cout << "---示例三---" << std::endl;
	father = new Son();
	delete father;

	system("pause");
	return 0;
}

运行截图:

在这里插入图片描述

在示例三中,竟然没有调用Son类的析构函数来释放内存,为什么会这样呢?

解决方案:

在基类的析构函数前加上 virtual 关键字

// 把Father类的析构函数定义为virtual函数时,
// 如果对 Father类的指针使用delete操作时,
// 就会对该指针使用“动态析构”:
// 如果这个指针,指向的是子类对象,
// 那么会先调用该子类的析构函数,再调用自己类的析构函数

virtual ~Father() {
		std::cout << "调用了Fahter类的析构函数" << std::endl;
		if (addr) {
			delete addr;
			addr = NULL;
		}
	}

运行截图:

在这里插入图片描述

【注意】
为了防止内存泄露,最好是在基类析构函数上添加virtual关键字,使基类析构函数为虚函数
目的在于,当使用delete释放基类指针时,会实现动态的析构:
1.如果基类指针指向的是基类对象,那么只调用基类的析构函数;
2.如果基类指针指向的是子类对象,那么先调用子类的析构函数,再调用父类的析构函数。


可别小看那一点点的内存就不要释放掉,积累成多,这个道理应该要懂得!

Windows环境下Elasticsearch与JDK版本兼容性实战指南 本文详细解析了Windows环境下Elasticsearch与JDK版本的兼容性问题,提供了从版本匹配检查到安装部署的完整实战指南。重点介绍了Elasticsearch 8.x需JDK 17+等关键版本对应关系,并分享多版本JDK共存方案及性能优化技巧,帮助开发者高效避坑。 阅读详情

相关推荐

扩视机器视觉—Halcon机器视觉48个实战项目六(检测定位角度)

此项目halcon检测检测定位角度问题,并显示。

qq_21516871的博客 1093

【C++】多态 ⑤ ( 虚析构函数 | 虚析构函数语法 | 虚析构函数意义 | 父类指针指向子类对象情况下父类和子类使用 virtual 虚析构函数 | 代码示例 )

一、虚析构函数 1、构造函数不能是虚函数 2、析构函数可以是虚函数 3、虚析构函数语法 4、虚析构函数意义 二、代码示例 - 虚析构函数 1、代码示例 - 没有使用虚析构函数导致子类析构函数无法调用 2、代码示例 - 使用虚析构函数正确示例

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 3998

ZYNQ裸机LWIP双网口实现

文章目录前言一、LWIP双网口二、使用步骤1.部分说明2.部分代码总结 前言 一、LWIP双网口 由于项目需要多通讯口,查阅资料发现lwip支持多网口操作。于是,就开搞了。 二、使用步骤 1.部分说明 利用xemac_add函数在网卡链表中添加一个网卡,即使用netif块重复xemac_add操作。 先用轮询的方式实现双网口,后期修改为中断模式 2.部分代码 导入官方例程LWip echo server, 修改main函数,增加一个netif块 #if LWIP_IPV6==0 #if L..

weixin_35865280的博客 1万+

C++继承时,关于构造函数以及为什么父类析构函数要定义为为虚析构函数的讲解

这个问题主要是由于子类继承父类时,构造函数和析构函数的调用问题产生的结果: 首先我们看构造原则: 如果子类没有定义构造方法,则调用父类的无参数的构造方法。 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数,则会调用父类的默认无参构造函数。 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类自己提供了无参构造函数,则会调用父类自己的无参构

双鱼座boyy的博客 2005

C语言实现定时任务

例:设置定时任务,每周周X的X时X分自动重启系统 思路:将设置好的重启时间保存到本地配置文件中,设置定时器定时一分钟,每一分钟信号触发一次事件,事件函数中获取配置文件信息与当前系统时间信息,将两个时间进行时间差计算,符合条件的自动重启系统. //创建定时器函数(通过信号触发事件timer_task函数启动) int create_timer() { struct sigevent evp; int ret = 0; memset(&evp, 0, sizeof(stru

佳佳鸽的博客 5036

【Unity URP渲染管线下Shader的自定义物体半透明和投影半透明效果_半透明案例分享】

Unity Shader Graph URP渲染管线下的自定义半透明效果_半透明案例分享

暴走约伯的博客 3295

C++基础知识 - 子类的析构函数

子类的析构函数 【注意】 为了防止内存泄露,最好是在基类析构函数上添加virtual关键字,使基类析构函数为虚函数 目的在于,当使用delete释放基类指针时,会实现动态的析构: 如果基类指针指向的是基类对象,那么只调用基类的析构函数 如果基类指针指向的是子类对象,那么先调用子类的析构函数,再调用父类的析构函数 #include <iostream> #include <Windows.h> using namespace std; class Father { public:

骆驼胡杨的博客 1370

华为OD机试真题 新系统 2026-09-06 Python&JS【仓储货物有序出库】

某仓储中心有一个货物堆放区,货物编号按乱序堆叠存放,只能从顶部取货,管理员需要将货物按编号从小到大取出。

MISAYAONE的博客 116

6. 继承

继承、虚函数

zheng131511的博客 357

【100%通过率】华为OD机试真题 Java&Go 实现【微服务的集成测试】【2023 Q1 | 100分】

现在有n个容器服务,服务的启动可能有一定的依赖性(有些服务启动没有依赖),其次服务自身启动加载会消耗些时间。给你一个nxn 的二维矩阵 useTime,其中 useTime=10 表示服务i自身启动加载需要消耗10s,useTimeli[j]=1 表示服务i 启动依赖服务i 启动完成,useTimei[k]=0,表示服务i 启动不依赖服务 k其实 0

MISAYAONE的博客 1万+

基于大语言模型的多轮对话系统优化研究

基于大语言模型的多轮对话系统优化研究 摘要 本研究针对大语言模型在多轮对话场景中的性能衰减问题,提出了一套系统优化方案。通过分层存储架构(短期记忆层、中期摘要层、长期知识层)和混合检索策略优化上下文管理,设计动态槽位填充框架增强对话状态跟踪,引入熵引导的重置算法改进生成策略,并采用双路径加载架构突破I/O瓶颈。实验表明,该方案使任务完成率提升28.6%,响应一致性提高41.2%,推理延迟降低35.8%,为构建高性能智能对话系统提供了实用技术路径。 关键词:大语言模型;多轮对话;上下文管理;状态跟踪~~~~~

huanghm88的专栏 663

C++中的析构函数

目录析构函数变量的生存期参考 析构函数 析构函数与构造函数功能相反,构造函数在对象被创建后调用,用于对对象的初始化,而析构函数在对象被销毁时调用,用于对对象内成员所占用的空间进行回收。 析构函数名称与类名相同,前方有一个“~”,没有返回值,没有参数(这一点与构造函数不同)。一个类只有一个析构函数。 如果定义类时没有编写析构函数,编译器会生成默认析构函数。如果程序员定义了一个析构函数,编译器不会再生成析构函数。 为了确保对象所占用的空间被回收,析构函数在对象声明期结束时会被自动调用(析构函数调用时机的原因:无

qq_40965507的博客 1030

华为od 面试八股文_Python语言_01_含答案

华为od 面试八股文_Python语言_01_含答案

MISAYAONE的博客 9106

C++遗失的子类析构函数

#include <iostream> #include <Windows.h> #include <string.h> using namespace std; class Father { public: Father(const char* addr ="中国"){ cout << "执行了Father的构造函数" << endl; int len = strlen(addr) + 1; this->addr = ne

C++ER的博客 479

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

多态--遗失的子类析构函数(重要)

结果完全符合我们的预期,但是就此可以说明我们的代码就完全正确或者说不存在致命错误?如果基类指针指向的是子类对象,那么先调用子类的虚构函数,再调用父类的析构函数.如果基类指针指向的是基类对象,那么只调用基类的析构函数;当使用delete释放基类指针时,会实现动态的析构;在基类(父类)析构函数上添加virtual关键字。子类的析构函数没有被执行。为了防止内存泄漏,最好是。,使基类析构函数为虚函数。用父类指针指向子类对象。

m0_68678128的博客 370

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

遗失的子类析构函数(内存泄漏)

```cpp #include <iostream> #include <Windows.h> #include <string.h> using namespace std; class Father { public: Father(const char* addr ="中国"){ cout << "执行了Father的构造函数" &...

weixin_39851178的博客 124

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C++多态(虚函数)使用详解

1.什么是多态 多态的本质: 形式上,使用统一的父类指针做一般性处理, 但是实际执行时,这个指针可能指向子类对象, 形式上,原本调用父类的方法,但是实际上会调用子类的同名方法。 1.1父类指针指向子类指针案例 #include <iostream> using namespace std; class Father { public: void play() { cout << "到KTV唱歌..." << endl; } }; class

qq_54169998的博客 2343

c++之说_9_5|自定义类型 struct 析构函数

/error 使用了B 的无参构造函数 但是B中没有 无参构造函数。// 函数结束 销毁函数栈中的栈变量 cobj 被销毁。// 函数结束 销毁函数栈中的栈变量 cobj 被销毁。注意 new 实例类型变量时 返回的是堆空间中的地址值 需要使用指针存储。//ok 使用了B 的有参函数。//归还堆空间 销毁该B类型的对象。//这里我感觉其实应该放调用类型的构造函数。delete 掉 C类型构造函数中的 new 出来的地址值。它是对象销毁时进行自动调用的 一般是拿来做清理工作的。

qq_59398646的博客 660

父类A a = new 子类B

首先什么是向上转型? 向上转型是JAVA中的一种调用方式,是多态的一种表现。向上转型并非是将B自动向上转型为A的对象,相反它是从另一种角度去理解向上两字的:它是对A的对象的方法的扩充,即A的对象可访问B从A中继承来的和B复写A的方法,其它的方法都不能访问,包括A中的私有成员方法。 比如标题: 1、a实际上指向的是一个子类对象,所以可以访问Dog类从Animal类继承的方法slee...

勇敢牛牛 1720

C++入门看这一篇就够了——超详细讲解(120000多字详细讲解,涵盖C++大量知识)

C++从入门到精通

m0_65635427的博客 7万+

C++ 内存泄露的原因及检测

一、原因 1. 在类的构造函数和析构函数中没有匹配的调用new和delete函数 两种情况下会出现这种内存泄露: 一是在堆里创建了对象占用了内存,但是没有显示地释放对象占用的内存; 二是在类的构造函数中动态的分配了内存,但是在析构函数中没有释放内存或者没有正确的释放内存 2.没有正确地清除嵌套的对象指针 3.在释放对象数组时在delete中没有使用方括号 ...

love、reading的博客 767

【阅读笔记】Effective C++

effective C++阅读笔记

Hawks的博客 893

多重继承Linux

系方式:QQ:31795882备注那个从哪看到文章 转本群:426500869 南京新生交流群:564025295 百度贴吧:南京新生交流吧 公众号:止观之路 最后要是想要资料加我私聊

qq_45035858的博客 122

C++笔记——c++编程思想(上)前3章

为了准备找工作,复习了一段时间的c++,而且有些内容当时复习了得还比较细致,做的笔记是纸质的,为了不使自己的这部分资料遗失,把它一点点放到网上来吧,从今天开始,一点一点。C++笔记——C++编程思想第一章 对象导言1. 面向对象三大特性:封装、继承、多态。2. C ++中的多态(晚捆绑)是通过虚函数实现的,在父类函数声明前加上关键字Virtual3. 把处理派生类型就如处理

zhangren07的专栏 1619

C++设计模式:装饰器模式

C++ STL 中的迭代器和算法:C++ STL(标准模板库)中的迭代器和算法也是装饰者模式的一个应用。并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。通过使用视图装饰器,我们可以在运行时动态地向视图函数添加额外的功能,例如权限验证、缓存控制等,而不需要修改原有的视图函数定义。Spring 框架中的 AOP(面向切面编程):Spring 框架中的 AOP 功能允许在不修改原有代码的情况下,通过添加切面来增强对象的功能。可以在运行时动态地向对象添加新的行为。

ajbb093的博客 486

【c++】c++基础知识

为了准备找工作,复习了一段时间的c++,而且有些内容当时复习了得还比较细致,做的笔记是纸质的,为了不使自己的这部分资料遗失,把它一点点放到网上来吧,从今天开始,一点一点。 C++笔记——C++编程思想 第一章 对象导言 1. 面向对象三大特性:封装、继承、多态。 2. C ++中的多态(晚捆绑)是通过虚函数实现的,在父类函数声明前加上关键字Virtual 3. 把处理派生类型就如处理基类

zjq_smile的博客 592
上一篇: C++11 final 与 override 的用法
下一篇: C++ 纯虚函数(抽象类)
cpp_learners
博客等级 码龄7年 1526粉丝 274原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值