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

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.xdnf.cn/news/870391.html

相关文章:

  • 【leetcode】9. 回文数
  • Hadoop大数据集群深度实践:源码分析、参数调优与自动化运维平台选型全解
  • 知识宇宙-学习篇:程序员调试思维
  • PyTest框架学习
  • docker镜像下载到本地,并导入服务器
  • spring4第6课-bean之间的关系+bean的作用范围
  • [C]extern声明变量报错:undefined reference终极解决方案
  • 《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- 第一篇:MIPI CSI-2基础入门
  • 【AAOS】【源码分析】用户管理(二)-- 用户启动
  • APx500录制波形
  • Qt Creator工具编译器配置
  • Oj系统测试报告
  • 第3章(新)Day3-Python逻辑语句
  • Java 创建线程池的几种方式
  • Python基础:文件简单操作
  • OpenCV CUDA模块图像处理------创建CUDA加速的Canny边缘检测器对象createCannyEdgeDetector()
  • 使用 useSearchParams 的一个没有触发控制台报错的错误用法
  • STL 库基础概念与示例
  • 洛谷每日1题-------Day39__P1697 [USACO18JAN] Lifeguards B
  • Vue 生命周期全解析:从创建到销毁的完整旅程
  • Redisson - 实现延迟队列
  • 通过ca证书的方式设置允许远程访问Docker服务
  • 吴恩达机器学习讲义概述
  • 在虚拟宇宙中低语——进程间通信,Linux命名管道的前世今生
  • 哈希表入门:用 C 语言实现简单哈希表(开放寻址法解决冲突)
  • 9.RV1126-OPENCV 视频的膨胀和腐蚀
  • 基于windows系统的netcore架构与SqlServer数据库,实现双机热备。
  • 基于javaweb的SpringBoot公司日常考勤系统设计与实现(源码+文档+部署讲解)
  • 新手小白深入 BCI:实践与进阶(下)
  • 函数调用(Function Calling)