深入理解C++智能指针系列(三)

引言

在现代软件开发中,内存管理是一个核心主题,特别是在使用C++这类需要手动管理内存的语言时。智能指针作为一种高效的工具,能够简化内存管理的复杂性。本文将讨论如何利用 std::unique_ptr 来封装复杂的内存管理任务,特别是在涉及栈上对象和多态性时的情况。通过使用定制删除器(custom deleter),我们可以灵活地控制内存的释放行为,从而适应更多复杂的使用场景。

正文

深入复制和多态克隆

假设我们要实现一个图形编辑软件,同一种图形在不同的构建场所有不同的效果,所以,我们一般会在图形类中维护一个构建指令:

class Shape {
public:explicit Shape(std::unique_ptr<Instructions> instructions): instructions_(std::move(instructions)) {}Shape(const Shape& other): instructions_(other.instructions_->clone()) {}
private:std::unique_ptr<Instructions> instructions_;
};

构建指令主要分为基础图形(BasicShape)和UML图形(UMLShape),另外,Instructions类具有多态克隆功能:

class Instructions {
public:virtual std::unique_ptr<Instructions> clone() const = 0;virtual ~Instructions() {}
};class BasicShape : public Instructions {
public:std::unique_ptr<Instructions> clone() const { return std::unique_ptr<Instructions>(new BasicShape(*this)); }
};class UMLShape : public Instructions {
public:std::unique_ptr<Instructions> clone() const { return std::unique_ptr<Instructions>(new UMLShape(*this)); }
};

构建一个Shape的方法如下:

enum class DrawingMethod {basicShape,umlShape
};Shape buildAShape(DrawingMethod method) {if (method == DrawingMethod::basicShape)return Shape(std::unique_ptr<Instructions>(new BasicShape));if (method == DrawingMethod::umlShape)return Shape(std::unique_ptr<Instructions>(new UMLShape));throw InvalidDrawingMethod();
}

正常的使用场景就是通过buildAShape方法创建Shape对象,但是在实际开发过程中,也可能会有其他方式去实现。比如,通过栈上的指令对象来创建临时的Shape对象:

UMLShape umlShape;
Shape shape(???); // 如何将 umlShape 传递给 shape?

这种情况下我们不能直接把unique_ptr绑定到栈分配的对象,因为栈对象在跳出作用域后会自动销毁,而使用unique_ptr会在指针对象跳出作用域时触发delete会导致未定义行为。

深入std::unique_ptr

std::unique_ptr是一个模板类,而且它还不止一个模板参数:

template<typename T,typename Deleter = std::default_delete<T>
> class unique_ptr;

std::default_delete<T>是一个调用delete的函数对象,它可以用自定义删除器替换。

解决方案

上面的问题是我们希望unique_ptr能够销毁Instructions,如果Instructions来自栈内存,那么我们就希望unique_ptr不会去销毁对象。
那么我们就通过多种删除器来解决这个问题:
删除器代码:

void deleteInstructions(const Instructions* instructions) { delete instructions; }
void doNotDeleteInstructions(const Instructions* instructions) {}

如何使用这些删除器呢:

using InstructionsUniquePtr = std::unique_ptr<const Instructions, void(*)(const Instructions*)>;enum class DrawingMethod {basicShape,umlShape
};Shape buildAShape(DrawingMethod method) {if (method == DrawingMethod::basicShape)return Shape(InstructionsUniquePtr(new BasicShape, deleteInstructions));if (method == DrawingMethod::umlShape)return Shape(InstructionsUniquePtr(new UMLShape, deleteInstructions));throw InvalidDrawingMethod();
}

如果指令对象来自栈:

UMLShape umlShape;
Shape shape(InstructionsUniquePtr(&umlShape, doNotDeleteInstructions));

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

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

相关文章

30秒学会一个ChatGpt-4o小技巧 --- 照片漫画化

文章目录 选择照片修改图片 选择照片 先选择自己的一张照片 当然首先你得能够访问ChatGpt-4o, 图片生成能力只有ChatGpt-4才有 所以我们先登录到 国内能够使用的ChatGpt网站: 我要超级GPT 然后把图片上传&#xff0c;再写提示词&#xff1a;请帮我把这种照片按照日系动漫风…

vue根据登录存储的性别来改变背景图

根据登录成功之后&#xff0c;并把信息存入到本地&#xff0c;在个人页面中&#xff0c;并取出来&#xff0c;并渲染它&#xff0c;这是一个根据存储的性别来渲染个人页面的背景图&#xff0c;男女性别不同&#xff0c;背景图也不一样。 template: <div class"top"…

IT 行业的现状剖析与未来展望:商业与技术的交织

今日&#xff0c;我无意间看到 CSDN 的创作话题&#xff1a;“我眼中的 IT 行业现状与未来趋势”&#xff0c;这引发了我对 IT 行业的深入思考。以下是我的一些个人见解&#xff0c;希望能得到大家的指正和交流&#xff0c;共同进步。 IT 行业的现状与未来趋势&#xff0c;这个…

云服务器有啥用?如何拥有一台自己的云服务器?

你们平时都把珍贵的学习资料藏在哪里&#xff1f; 你们是否也遇到过学习资料丢失&#xff0c;或者放在网盘被人发现的问题&#xff1f; 云服务器作为一种灵活、高效、可扩展的计算资源&#xff0c;为用户提供了强大的计算能力和存储空间。所以我们可以尝试通过云服务器来搭建…

【Gtest使用说明】

主要测试的代码 #include <gtest/gtest.h> int add(int a, int b) {return a b; } TEST(MathTest, Add) {EXPECT_EQ(3, add(1, 2));EXPECT_EQ(9, add(2, 3));} int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS(); …

821. 字符的最短距离 - 力扣

1. 题目 给你一个字符串 s 和一个字符 c &#xff0c;且 c 是 s 中出现过的字符。 返回一个整数数组 answer &#xff0c;其中 answer.length s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 的字符 c 的 距离 。 两个下标 i 和 j 之间的 距离 为 abs(i - j) &#xff0c…

代码随想录算法训练营day36 | 1005.K次取反后最大化的数组和、134. 加油站、135. 分发糖果

1005.K次取反后最大化的数组和 分几步做&#xff0c;思路清晰 按绝对值从大到小的顺序进行排序从前向后遍历&#xff0c;遇到负数将其变为正数&#xff0c;同时K--如果K还大于0&#xff0c;那么反复转变数值最小的元素&#xff0c;将K用完求和 class Solution:def largestSu…

el-transfer和el-tree进行结合搞一个树形穿梭框

由于业务需求需要在穿梭框里使用树形结构&#xff0c;但是本身element里并不支持&#xff0c;于是参考了别的大佬发的文章作为思路及后续自己新增了一些处理功能。 目录 1.拷贝代码放到自己的项目目录中 2.改造el-transfer的源码 3.修改tree-transfer-panel.vue文件 4.修改…

数据挖掘实战-基于余弦相似度的印度美食推荐系统

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【模版方法设计模式】

文章目录 模板方法设计模式模板方法的设计原则模板方法设计模式组成部分代码实现抽象类实现具体实现类执行 模板方法设计模式 模版方法设计模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一个操作中的算法骨架&#xff0c;而将一…

最最最重要的集群参数配置(上)no.7

我希望通过两期内容把这些重要的配置讲清楚。严格来说这些配置并不单单指Kafka服务器端的配置&#xff0c;其中既有Broker端参数&#xff0c;也有主题&#xff08;后面我用我们更熟悉的Topic表示&#xff09;级别的参数、JVM端参数和操作系统级别的参数。 需要你注意的是&…

MATLAB导入导出Excel的方法|读与写Excel的命令|附例程的github下载链接

前言 前段时间遇到一个需求&#xff1a;导出变量到Excel里面&#xff0c;这里给出一些命令&#xff0c;同时给一个示例供大家参考。 MATLAB读/写Excel的命令 在MATLAB中&#xff0c;可以使用以下命令来读写Excel文件&#xff1a; 读取Excel文件&#xff1a; xlsread(filen…

Java EE-Spring AOP 面向切面编程

Spring AOP https://www.cnblogs.com/joy99/p/10941543.html 超级详细版&#xff1a;Chapter 6. 使用Spring进行面向切面编程&#xff08;AOP&#xff09; AOP 原理 面向切面 ( Aspect Orient Programming ) 面向切面编程&#xff0c;是面向对象编程(OOP) 的一种补充。 在…

基于Qt的网上购物系统的设计与实现

企鹅&#xff1a;2583550535 代码和论文都有 第1章 绪论... 1 1.1 项目背景... 1 1.2 国内外研究现状... 1 1.3 项目开发意义... 3 1.4 报告主要内容... 3 第2章 关键技术介绍... 4 2.1 后端开发技术... 4 2.1.1 C. 4 2.1.2 Qt框架... 4 2.1.3 MySQL数据库... 5 2.2 …

信息学奥赛一本通(C++版)2034:【例5.1】反序输出

题目描述 输入&#x1d45b;个数,要求程序按输入时的逆序把这&#x1d45b;个数打印出来&#xff0c;已知整数不超过100个。也就是说&#xff0c;按输入相反顺序打印这&#x1d45b;个数。 输入 输入一行共有&#x1d45b;个数&#xff0c;每个数之间用空格隔开。 输出 如题要求…

CentOS 7 搭建mqtt服务简介

在CentOS 7上搭建MQTT服务&#xff0c;你可以选择一个MQTT broker来实现。一个流行的选择是Eclipse Mosquitto&#xff0c;它是一个轻量级的MQTT broker&#xff0c;非常适合在资源有限的系统上运行。以下是在CentOS 7上安装和配置Eclipse Mosquitto的步骤&#xff1a; 1. 安装…

windows 自定义scheme协议

注册表里面按照如下格式填写自定义scheme协议即可&#xff1a;Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\jdtest] "URL:jdtest Protocol" "URL Protocol"""[HKEY_CURRENT_USER\jdtest\DefaultIcon] "E:\\Program Files (x86…

德勤:中国、印度等对ChatGPT等生成式AI应用,处领先地位

全球四大会计事务所之一的德勤&#xff08;Deloitte&#xff09;在官网发布了一份&#xff0c;名为《Generative AI in Asia Pacific: Young employees lead as employers play catch-up》的深度调查报告。 主要查看中国、澳大利亚、印度、日本、新加坡、韩国、中国台湾等亚太…

Prompt Engineering Guide

本文转载自&#xff1a;Prompt Engineering Guide https://www.promptingguide.ai/zh/introduction/basics 文章目录 提示工程简介1、基本概念1&#xff09;基础提示词2&#xff09;提示词格式 2、提示词要素3、设计提示的通用技巧从简单开始指令具体性避免不精确做还是不做&am…

操作系统实验:进程和线程同步和互斥(生产者消费者问题,睡觉的理发师问题)

1.生产者消费者问题&#xff08;信号量&#xff09; 参考教材中的生产者消费者算法&#xff0c;创建5个进程&#xff0c;其中两个进程为生产者进程&#xff0c;3个进程为消费者进程。一个生产者进程试图不断地在一个缓冲中写入大写字母&#xff0c;另一个生产者进程试图不断地…