优雅回收多个成员变量内存——使用函数模板实现内存安全释放

news2024/9/19 10:36:49

目录

  • 从析构类中的多个成员说起
  • 什么是函数模板
  • 使用函数模板

从析构类中的多个成员说起

你有没有遇到过这种情况,一个类的构造函数中new了很多个成员变量,在析构函数中回收内存时,写了一遍又一遍 下面的代码:

if (ptr != nullptr) {
	delete ptr;
	ptr = nullptr;
}

看一个例子:
B.h

#ifndef SAFEDELETE_B_H
#define SAFEDELETE_B_H


class B {
public:
    explicit B();
    ~B();
};


#endif //SAFEDELETE_B_H

B.cpp

#include <iostream>
#include "B.h"

B::B() {

}

B::~B() {
    std::cout << "destroy B..." << std::endl;
}

C.h

#ifndef SAFEDELETE_C_H
#define SAFEDELETE_C_H


class C {
public:
    explicit C();
    ~C();
};


#endif //SAFEDELETE_C_H

C.cpp

#include <iostream>
#include "C.h"

C::C() {

}

C::~C() {
    std::cout << "destroy C..." << std::endl;
}

A.h

#ifndef SAFEDELETE_A_H
#define SAFEDELETE_A_H
#include "B.h"
#include "C.h"

class A {
public:
    explicit A();
    ~A();

private:
    B* b{nullptr};
    C* c{nullptr};
};

#endif //SAFEDELETE_A_H

A.cpp

#include <iostream>
#include "A.h"

A::A() {
    b = new B();
    c = new C();
}

A::~A() {
    if (b != nullptr) {
        delete b;
        b = nullptr;
    }
    if (c != nullptr) {
        delete c;
        c = nullptr;
    }
    std::cout << "destroy A..." << std::endl;
}

在A的析构函数中释放b、c的内存时,写了6行代码,如果有20甚至更多数量的成员时,析构函数就显得很臃肿。
这种情况在使用Qt的时候尤为常见,一个类中可能有数十个控件,最后回收内存的时候,光写delete都有将近百十行代码。这时候,如果再有编码规范限制你一个函数不能超过50行,是不是很崩溃?你可能会说,没关系我可以抽几个函数出来,这样确实也能解决问题,但是纯粹为了抽函数而抽不是最佳方法,下面分享另一种更实用的方法——函数模板。

什么是函数模板

C++的函数模板是‌泛型编程的基础,‌它允许定义一种与类型无关的通用函数‌。‌通过使用模板,‌可以编写出适用于多种数据类型的函数,‌而无需为每种类型单独编写代码。‌函数模板的定义以关键字template开始,‌后跟模板参数列表,‌通常是typename T,‌其中T是一个占位符,‌代表任意类型。‌在函数模板的定义中,‌可以使用T来代表函数的参数类型、‌返回值类型或函数体内的变量类型。‌当调用函数模板时,‌编译器会根据实参的类型自动推断出模板参数T的具体类型,‌从而生成相应类型的函数实例。‌这种机制极大地提高了代码的复用性和灵活性‌。

使用函数模板

看到这种重复代码,相信你已经想到了有没有一种通用的方法可以解决不同类对象的析构问题,答案是肯定的。
使用函数模板,将类型忽略,就可以写出下面的函数:

template<typename T>
void safeDelete(T *&ptr) {
    if (ptr != nullptr) {
        delete ptr;
        ptr = nullptr;
    }
}

在A类中加入模板函数,修改析构函数:
A.cpp

#include <iostream>
#include "A.h"

A::A() {
    b = new B();
    c = new C();
}

A::~A() {
    safeDelete(b);
    safeDelete(c);
    std::cout << "destroy A..." << std::endl;
}

// 使用函数模板
template<typename T>
void A::safeDelete(T *&ptr) {
    if (ptr != nullptr) {
        delete ptr;
        ptr = nullptr;
    }
}

在main函数中delete A类的对象,

#include <iostream>
#include "A.h"

using namespace std;

int main() {
    A* a = new A();
    delete a;
    a = nullptr;

    return 0;
}

运行结果:
在这里插入图片描述
使用函数模板就可以解决析构函数中写太多if的问题,代码看起来也很优雅!

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

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

相关文章

EXCEL文件如何批量加密,有什么方法

EXCEL文件的加密&#xff0c;通常在EXCEL软件上进行设置&#xff0c;它有打开密码与写保护密码&#xff0c;如果有多个文件的话&#xff0c;想通过一键设置的方法进行密码设置&#xff0c;那么它通常需要用到第三方软件进行批处理&#xff0c;因为EXCEL软件只能对当前打开的文件…

Wan-本科阶段部分作品

1、简易无接触温度测量与身份识别装置&#xff08;电赛 省一&#xff09; 2、基于交叉带式分拣结构的智能垃圾分类系统&#xff08;工训赛 省二&#xff09; 3、基于STM32的智能语音风扇&#xff08;大创优秀结题&#xff09;

鸿蒙界面开发(八):Grid网格布局Badge角标组件

Badge角标组件 在目标组件的外层包裹一层Badge角标组件 支持位置&#xff1a;右上&#xff0c;左&#xff0c;右 也可以使用绝对定位实现更灵活的角标位置。 Badge({count:1,//角标数值&#xff0c;角标数值为0时不展示position:BadgePosition.RightTop,//角标位置&#xff0…

【工作实践】MVEL 2.x语法指南

目录标题 MVEL 2.x语法指南一、基本语法1. 简单属性表达式2. 复合语句3. 返回值 二、值判断1. 判断空值2. 判断Null值3. 强制转换 三、内联Lists、Maps和数组Arrays1. Lists2. Maps3. 数组Arrays4. 数组强制转换 四、属性导航1. Bean属性2. Bean的安全属性导航3. 集合(1). List…

BOSS AI

BOSS AI 人工智能一点也不智能啊&#xff0c;机器人都不考虑用户的需求和体验吗&#xff1f; 这么多&#xff0c;我怎么看&#xff0c;我也不知道对面是人呢&#xff1f;还是机器人&#xff1f; 然后推送的东西也不知道我想要的&#xff0c;难道年龄到了&#xff0c;就活该天…

在 Windows 11上安装 .NET Framework 3.5

在 Windows 11上安装 .NET Framework 3.5 在控制面板中启用 .NET Framework 3.5 在安装某些软件时&#xff0c;会弹出以下界面&#xff0c;显示需要安装【 .NET Framework 3.5】。 安装微软官方建议进行安装&#xff1a; Microsoft-https://learn.microsoft.com/zh-cn/dotnet…

性能测试的方法有哪些?

性能测试是软件开发过程中非常重要的一环&#xff0c;它能够评估系统的性能以及稳定性。在进行性能测试之前&#xff0c;需要制定一系列的测试方法和策略&#xff0c;以确保测试的准确性和有效性。下面是一篇详细且规范的文章&#xff0c;介绍了性能测试的方法。 第一部分&…

Python中排序算法之冒泡排序

排序算法是将给定的数列中的数进行升序&#xff08;从小到大&#xff09;或者降序&#xff08;从大到小&#xff09;排列。冒泡排序是排序算法的一种。 1 冒泡排序的原理 1.1 基本思想 冒泡排序是将数据中较大或者较小的数据依次向右推移的一种排序技术。它的基本思想是比较…

js实现3d拖拽环绕旋转

js实现拖动节点围绕圆心转动 1.使用transform属性&#xff0c;将圆环放倒展示为椭圆 圆环上有不同的色彩&#xff0c;在转动的同时&#xff0c;需要让圆环也转动&#xff0c;所以圆环不能是椭圆&#xff0c;而是圆形&#xff0c;这样在转动的时候&#xff0c;改变rotate&…

Cypress第二次安装遇到的问题

问题一&#xff1a;吐血&#xff0c;谁会想到node.js的官网访问不了呢&#xff01; 中文网站&#xff1a;http://url.nodejs.cn/download/ 官网&#xff1a;https://nodejs.org/zh-cn nodejs安装的两种方法(官网、NVM安装-node版本切换)不知道这种方式是否可行&#xff0c;还…

Android UI绘制原理:UI的绘制流程是怎么样呢?为什么子线程不能刷新UI呢?讲解大体的流程是怎么样的

目录&#xff1a; 为什么子线程不能刷新UI呢&#xff0c;原因是什么&#xff1f;UI绘制原理 2.1 创建Activity 实例和view的树型结构 2.2 管理绘制的类&#xff1a;ViewRootImpl 2.3 是如何触发刷新View的&#xff1f; 2.4 View的绘制流程&#xff1a;测量(Measure) 2.5 View的…

1998-2023年上市公司研发投入数据

1998-2023年上市公司研发投入数据 1、时间&#xff1a;1998-2023年 2、来源&#xff1a;上市公司年报 3、指标&#xff1a;证券代码、统计截止日期、数据来源、报表类型、研发人员数量&#xff08;人&#xff09;、研发人员数量占比(%)、研发投入金额&#xff08;元&#xf…

MyBatis一级缓存和二级缓存以及 mybatis架构

缓存 数据缓存&#xff0c;让数据离我们执行的程序更近一点&#xff0c;让程序能够快速的获取到数据 缓存的作用就是减轻数据库的压力&#xff0c;提高查询性能。缓存实现的原理是从数据库中查询出来的对象在使用完后不要销毁&#xff0c;而是存储在内内&#xff08;缓存&…

亚马逊无货源店群模式是什么?2024年还能做吗?

相信众多的电商卖家&#xff0c;对店群模式并不陌生。近年来国内电商的店群模式竞争激烈&#xff0c;近乎饱和。那么&#xff0c;在国际知名的跨境电商平台亚马逊上&#xff0c;店群模式又是如何运作呢&#xff1f;到了2024年&#xff0c;亚马逊的店群模式还值得做吗&#xff1…

EAST文本检测

原文:EAST文本检测 - 知乎 (zhihu.com) 一、文本检测 论文: https://arxiv.org/pdf/1704.03155.pdf​arxiv.org/pdf/1704.03155.pdf 一般的文本检测模型会分多个阶段(multi-stage)进行,在训练时需要把文本检测切割成多个阶段(stage)来进行学习,这种把完整文本行先分…

表达式求值问题的实现

这是C算法基础-数据结构专栏的第二十二篇文章&#xff0c;专栏详情请见此处。 引入 相信大家都会做如1(23)*4/5-6这样的算式&#xff0c;而我们今天要学习让计算机通过表达式求它的值&#xff0c;这就是表达式求值问题。 下面我们就来讲表达式求值问题的实现。 定义 表达式求值…

mysql的聚簇索引、非聚簇索引、回表

1.聚簇索引和非聚簇索引 聚簇索引&#xff08;聚集索引&#xff09;&#xff1a;数据和索引放在一起&#xff0c;B树的叶子节点存放了整行数据&#xff0c;有且只有一个。 【主键索引和唯一索引&#xff0c;主键唯一&#xff0c;存放的是主键对应的整行数据】非聚簇索引&#…

[CR]厚云填补_Diffusion Enhancement for CR

Diffusion Enhancement for Cloud Removal in Ultra-Resolution Remote Sensing Imagery Abstract 云层的存在严重影响了光学遥感图像的质量和有效性。然而&#xff0c;现有的基于深度学习(DL)的云移除(CR)技术&#xff0c;通常以保真度驱动的损失作为约束&#xff0c;例如L1或…

USB3.2 摘录(11)

系列文章目录 USB3.2 摘录&#xff08;一&#xff09; USB3.2 摘录&#xff08;二&#xff09; USB3.2 摘录&#xff08;三&#xff09; USB3.2 摘录&#xff08;四&#xff09; USB3.2 摘录&#xff08;五&#xff09; USB3.2 摘录&#xff08;六&#xff09; USB3.2 摘录&…

OpenAI神秘“草莓”项目 计划最早今年秋季推出

据科技媒体The Information报道&#xff0c;OpenAI神秘“草莓”项目&#xff0c;计划最早今年秋季推出&#xff01;上个月&#xff0c;OpenAI的内部团队被曝出正开发的“草莓”&#xff08;Strawberry&#xff09;项目&#xff0c;目的是增强OpenAI的模型的推理能力&#xff0c…