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

C++——智能指针 unique_ptr

unique_ptr的实现原理:简单粗暴的防拷贝

目录

一、使用C++11中的新用法unique_ptr

二、使用c++11模拟实现

三、使用c++98特性实现

四、模拟实现unique_ptr

五、发现问题


 

一、使用C++11中的新用法unique_ptr

由于限制了拷贝以及赋值
导致缺陷:unique_ptr管理的资源无法共享

void TestUniquePtr()
{unique_ptr<int> up1(new int(10));*up1 = 100;// unique_ptr<int> up2(up1);  // 无法进行拷贝构造unique_ptr<int> up3;// up3 = up1;				  // 无法进行赋值运算符重载
}int main()
{TestUniquePtr();_CrtDumpMemoryLeaks();return 0;
}

二、使用c++11模拟实现

使用了 C++11 =delete 这个语法的特性
“尝试引用已经删除的函数”
class CopyBan
{
public:CopyBan(int c): _c(c){}// c++11 实现方式CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;
private:int _c;
};

三、使用c++98特性实现

将拷贝构造 以及 赋值运算符重载 只声明不定义
并且将其访问权限设置为 private
class CopyBan
{
public:CopyBan(int c): _c(c){}// c++98 实现方式
private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);int _c;
};

四、模拟实现unique_ptr

无法进行拷贝构造以及对象赋值

#include<iostream>namespace wei
{template<class T>class unique_ptr{public:// RAIIunique_ptr(T* ptr = nullptr): _ptr(ptr){ }~unique_ptr(){if (_ptr){delete _ptr;_ptr = nullptr;}}// 具有指针类似的行为T& operator*(){return *_ptr;}T* operator->(){return _ptr;}T* get(){return _ptr;}// 禁止拷贝/*C++98 只声明不定义拷贝构造函数和赋值运算符重载函数,并将权限修改为privateprivate:unique_ptr(const unique_ptr<T>&);unique_ptr<T> operator=(const unique_ptr<T>&);*/C++11unique_ptr(const unique_ptr<T>&) = delete;unique_ptr<T> operator=(const unique_ptr<T>&) = delete;private:T* _ptr;};
}void TestUniquePtr()
{wei::unique_ptr<int> up1(new int(10));*up1 = 100;wei::unique_ptr<int> up2(up1);  拷贝报错wei::unique_ptr<int> up3(new int(10));up3 = up1;  赋值报错
}int main()
{TestUniquePtr();_CrtDumpMemoryLeaks();return 0;
}

五、发现问题

        再析构的时候只能进行delete,但如果用malloc申请的空间,就无法进行释放,因为new和delete配套,malloc和free配套,如果有其他类型的空间更无法进行释放,例如FILE类型文件,fopen和fclose配套。

namespace bite
{template<class T>class DFDef{public:void operator()(T*& ptr){if (ptr){delete ptr;ptr = nullptr;}}};增加一个模版参数,默认使用DFDef的方法进行delete释放资源template<class T, class DF = DFDef<T>>  class unique_ptr{public:// RAIIunique_ptr(T* ptr = nullptr): _ptr(ptr){}~unique_ptr(){if (_ptr){//delete _ptr;// 应该根据用户提供的资源方式去释放//DF df;//df.operator()(_ptr);  这几种方式均可以//df(_ptr);DF()(_ptr);}}// 具有指针类似的行为T& operator*(){return *_ptr;}T* operator->(){return _ptr;}T* get(){return _ptr;}// 防拷贝// C++11unique_ptr(const unique_ptr<T>&) = delete;unique_ptr<T> operator=(const unique_ptr<T>&) = delete;private:T* _ptr;};
}template<class T>
class Free
{
public:void operator()(T*& ptr)    其他的几种重载调用{if (ptr){free(ptr);ptr = nullptr;}}
};class FClose
{
public:void operator()(FILE*& ptr){if (ptr){fclose(ptr);ptr = nullptr;}}
};template<class T>
class deleteArray
{
public:void operator()(T*& ptr){if (ptr){delete[] ptr;ptr = nullptr;}}
};#include <malloc.h>
void TestUniquePtr()
{bite::unique_ptr<int> up1(new int(10));*up1 = 100;bite::unique_ptr<int, Free<int>> up2((int*)malloc(sizeof(int)));bite::unique_ptr<FILE, FClose> up3(fopen("111.txt", "w"));// bite::unique_ptr<int> up4(new int[10]);// 注意:一般不会将连续的空间使用unique_ptr管理// 因为:STL中已经存在了vector
}// 缺陷:unique_ptr管理的资源无法共享
int main()
{TestUniquePtr();_CrtDumpMemoryLeaks();return 0;
}

http://www.lryc.cn/news/2400733.html

相关文章:

  • 【Python训练营打卡】day43 @浙大疏锦行
  • 1-【源码剖析】kafka核心概念
  • JavaScript中判断两个对象是否相同(所有属性的值是否都相同)
  • Flask 应用的生产环境部署指南
  • 思科设备网络实验
  • Oracle OCP与MySQL OCP认证如何选?
  • AWS之数据分析
  • C# Onnx 动漫人物头部检测
  • 【Ragflow】24.Ragflow-plus开发日志:增加分词逻辑,修复关键词检索失效问题
  • gin 常见中间件配置
  • 蚂蚁森林自动收能量助手:Ant_Forest_1_5_4_3绿色行动新选择
  • Zookeeper 集群部署与故障转移
  • Redis最佳实践——电商应用的性能监控与告警体系设计详解
  • 区域徘徊检测算法AI智能分析网关V4助力公共场所/工厂等多场景安全升级
  • 修复与升级suse linux
  • 电力高空作业安全检测(2)数据集构建
  • 嵌入式开发之STM32学习笔记day18
  • [论文阅读]PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning
  • 一键 Ubuntu、Debian、Centos 换源(阿里源、腾讯源等)
  • 汽车安全:功能安全FuSa、预期功能安全SOTIF与网络安全Cybersecurity 解析
  • 【C++高级主题】虚继承
  • 基于 ZYNQ 的实时运动目标检测系统设计
  • 数据结构(JAVA版)练习题
  • C#编程过程中变量用中文有啥影响?
  • 哈希表入门:用 C 语言实现简单哈希表(开放寻址法解决冲突)
  • [华为eNSP] 在eNSP上实现IPv4地址以及IPv4静态路由的配置
  • 2024年第十五届蓝桥杯青少组c++国赛真题——快速分解质因数
  • 【动手学MCP从0到1】2.1 SDK介绍和第一个MCP创建的步骤详解
  • 基于MyBatis插件实现动态表名解决多环境单一数据库问题
  • 测试面试题总结一