当前位置: 首页 > 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.lqws.cn/news/122833.html

相关文章:

  • 微信小程序动态组件加载的应用场景与实现方式
  • 3D动画在微信小程序的实现方法
  • Quipus系统的视频知识库的构建原理及使用
  • 让音乐“看得见”:使用 HTML + JavaScript 实现酷炫的音频可视化播放器
  • 英国2025年战略防御评估报告:网络与电磁域成现代战争核心
  • 【从GEO数据库批量下载数据】
  • matlab基于GUI实现水果识别
  • mybatis 参数绑定错误示范(1)
  • 磐云P10 P057-综合渗透测试-使用反弹木马进行提权获取主机Shell
  • 【.net core】【watercloud】树形组件combotree导入及调用
  • .NET Core接口IServiceProvider
  • WebFuture:Ubuntu 系统上在线安装.NET Core 8 的步骤
  • 结构型设计模式之Proxy(代理)
  • 【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
  • 代码随想录算法训练营第60期第五十七天打卡
  • Kafka消息队列
  • 《Docker》架构
  • 1.springmvc基础入门(一)
  • pytorch 与 张量的处理
  • Leetcode日记
  • 如何确定微服务的粒度与边界
  • sql server如何创建表导入excel的数据
  • 结节性甲状腺肿全流程大模型预测与决策系统总体架构设计方案大纲
  • 互联网大厂Java求职面试:云原生架构下的微服务网关与可观测性设计
  • MDP的recoders部分
  • Python基础:文件简单操作
  • .Net Framework 4/C# 属性和方法
  • 【手写系列】手写动态代理
  • C++——智能指针 weak_ptr
  • Java多线程:ThreadPoolTaskExecutor线程池 与CompletableFuture如何打出组合拳