当前位置: 首页 > news >正文

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

引言

前面两篇介绍了std::unique_ptr的自定义删除器以及如何优化删除器的使用。
本文将介绍std::unique_ptr在使用过程中的一些“奇技淫巧”。

正文

删除器和std::move

std::move是将对象的所有权转移给另一个对象,那如果通过std::move来转移带自定义删除器的std::unique_ptr对象时,对应的删除器会不会一起转移呢?

我们通过示例定义奇偶数的删除器来介绍:

void deleteEvenNumber(int* pi)
{std::cout << "Delete even number " << *pi << '\n';delete pi;
}void deleteOddNumber(int* pi)
{std::cout << "Delete odd number " << *pi << '\n';delete pi;
}using IntDeleter = void(*)(int*);
using IntUniquePtr = std::unique_ptr<int, IntDeleter>;int main() {{IntUniquePtr p1(new int(42), deleteEvenNumber);IntUniquePtr p2(new int(43), deleteOddNumber);p1 = move(p2);}return 0;
}

上面这个示例中,如果把p1 = move(p2);代码注释掉,它的结果是:

Delete odd number 43
Delete even number 42

如果把代码还原回去后,结构是:

Delete even number 42
Delete odd number 43

从上面两个结果来看,std::move不仅把对象的所有权转移了,同时也转移了删除器。

删除器和reset()

std::unique_ptrreset()函数是用来重置智能指针的状态和其管理的对象。如果unique_ptr定义了删除器,然后调用reset()会出现什么效果呢?
还是用上面的示例,修改main()函数:

int main() {{IntUniquePtr p1(new int(42), deleteEvenNumber);p1.reset(new int(43));}return 0;
}

结果是:

Delete even number 42
Delete even number 43

这个结果就说明reset()不会对删除器产生任何影响。
但是这就产生一个问题,重置后的值并不是偶数,对应的删除器已经不符合需求了,但是reset()又只能传一个参数,没有通过reset()重置删除器,那要怎么解决呢?

方案一:

因为std::unique_ptr提供了get_deleter()函数来返回删除器的引用,所以我们可以通过该接口来手动修改删除器:

int main() {{IntUniquePtr p1(new int(42), deleteEvenNumber);p1.reset(new int(43));p1.get_deleter() = deleteOddNumber;}return 0;
}

运行结果:

Delete even number 42
Delete odd number 43

方案二:

第二种方案是用赋值来代替reset()

int main() {{IntUniquePtr p1(new int(42), deleteEvenNumber);p1 = IntUniquePtr(new int(43), deleteOddNumber);}return 0;
}

运行结果:

Delete even number 42
Delete odd number 43
http://www.lryc.cn/news/355355.html

相关文章:

  • 1.Nginx上配置 HTTPS
  • wordpress教程视频 wordpress教程网盘 wordpress教程推荐wordpress教程网
  • vue3 3D炫酷模型banner图
  • 小程序内使用路由
  • 【数据结构】第七节:堆
  • 前端大师-高级Web开发测验
  • 延迟初始化和密封类
  • Kotlin基础之基本语法
  • 多态(难的起飞)
  • 安装GO环境
  • 记一次由于代码原因导致Mysql连接被打满和唯一索引重复问题
  • redis数据类型之string,list
  • Android android.os.DeadObjectException aidl通信异常分析及解决
  • dp + 计数,1954D - Colored Balls
  • 【设计模式深度剖析】【5】【结构型】【桥接模式】| 以电视和遥控器为例加深理解
  • 一键安装脚本sh
  • WebGL在医学成像方面的应用
  • SpringBoot+layuimini实现角色权限菜单增删改查(layui扩展组件 dtree)
  • 项目范围管理
  • 监管端..
  • 点击登录按钮先检测输入框的规则检测(vue组合式)
  • 网络工程师---第四十二天
  • leetcode 1241每个帖子的评论数(postgresql)
  • 前端最新面试题(ES6模块篇)
  • STM32H750外设之ADC通道选择
  • 【Unity2D 2022:Cinemachine】相机跟随与地图边界
  • ssh远程连接的相关配置
  • 在leafet上画圆、多边形、线、矩形
  • SpringBoot中如何在服务器进行校验?
  • element ui 的el-input输入一个字后失去焦点,需重新点击输入框才能再次输入