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

简化版unique_ptr说明其本质

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

      • 简化版 `unique_ptr` 核心实现
      • 核心原理拆解(对应代码)
      • 测试代码(验证核心逻辑)
      • 总结

我们平时自己写的类只有实现了移动构造函数,并且再移动构造函数内正确书写移动构造逻辑,我们的这个类才真正的能够按照移动语义做事,真正发挥移动语义的作用,同理独占指针是一个模板类是吧,它本身是不是就是进制拷贝构造和赋值运算符,并且实现了移动构造,由此形成了自身的特点,不能拷贝,只能够移动,你可以大致用代码描述下独占指针实现,伪代码也行主要说明白原理

你的理解完全正确!核心结论先明确:

  • 自定义类要发挥移动语义的价值,必须显式/隐式实现移动构造函数移动赋值运算符,并在其中完成“资源所有权转移+原对象置空”的逻辑;
  • std::unique_ptr本质是一个模板类,它的核心实现逻辑就是:禁用拷贝构造/拷贝赋值实现移动构造/移动赋值,同时结合 RAII 机制自动释放资源,最终实现“独占所有权、仅可移动”的特性。

下面用简化版伪代码还原unique_ptr的核心实现逻辑(省略了数组版本、自定义删除器等扩展功能,只保留核心原理),帮你直观理解:

简化版unique_ptr核心实现

// 模板类:支持任意类型的动态内存管理template<typenameT>classMyUniquePtr{public:// 1. 构造函数:接管裸指针的所有权(RAII:资源获取即初始化)explicitMyUniquePtr(T*ptr=nullptr):m_ptr(ptr){}// 2. 禁用拷贝构造函数:保证独占性(C++11用delete)MyUniquePtr(constMyUniquePtr&other)=delete;// 3. 禁用拷贝赋值运算符:避免所有权被拷贝MyUniquePtr&operator=(constMyUniquePtr&other)=delete;// 4. 移动构造函数:转移所有权(核心!)// 参数是右值引用(&&),接收临时对象/被move的对象MyUniquePtr(MyUniquePtr&&other)noexcept{// 第一步:接管对方的资源(指针)m_ptr=other.m_ptr;// 第二步:将原对象的指针置空,避免析构时重复释放other.m_ptr=nullptr;}// 5. 移动赋值运算符:转移所有权(核心!)MyUniquePtr&operator=(MyUniquePtr&&other)noexcept{// 第一步:先释放当前对象持有的资源(避免内存泄漏)if(this!=&other){// 防止自赋值deletem_ptr;// 第二步:接管对方的资源m_ptr=other.m_ptr;// 第三步:原对象置空other.m_ptr=nullptr;}return*this;}// 6. 析构函数:自动释放资源(RAII的关键)~MyUniquePtr(){deletem_ptr;// 独占指针析构时,释放持有的动态资源}// ========== 模拟指针的核心行为 ==========// 重载解引用运算符:*ptrT&operator*()const{return*m_ptr;}// 重载箭头运算符:ptr->func()T*operator->()const{returnm_ptr;}// ========== 辅助方法 ==========// 手动释放资源(可选)voidreset(T*new_ptr=nullptr){deletem_ptr;m_ptr=new_ptr;}// 转移所有权(返回裸指针,原对象置空)T*release(){T*temp=m_ptr;m_ptr=nullptr;returntemp;}// 获取内部裸指针(谨慎使用)T*get()const{returnm_ptr;}private:T*m_ptr;// 核心:封装的裸指针,唯一持有资源所有权};

核心原理拆解(对应代码)

  1. 独占性的保证:禁用拷贝

    • MyUniquePtr(const MyUniquePtr&) = delete;operator=(const MyUniquePtr&) = delete;直接禁用了拷贝构造和拷贝赋值,从语言层面杜绝了“多个MyUniquePtr持有同一个资源”的可能,这是“独占”的核心。
  2. 移动语义的落地:所有权转移

    • 移动构造/移动赋值的参数是右值引用(&&),只能接收临时对象(如函数返回值)或被std::move标记的对象;
    • 移动时做两件关键事:
      • 接管对方的指针(m_ptr = other.m_ptr);
      • 把原对象的指针置空(other.m_ptr = nullptr),避免原对象析构时重复释放资源。
  3. RAII 自动释放:无需手动 delete

    • 析构函数~MyUniquePtr()会自动调用delete m_ptr,只要MyUniquePtr对象生命周期结束(如出作用域、被销毁),就会自动释放资源,彻底解决裸指针“忘记 delete”的问题。
  4. 模拟指针行为:易用性

    • 重载*->运算符,让MyUniquePtr能像裸指针一样使用(ptr->func()*ptr),降低使用成本。

测试代码(验证核心逻辑)

// 测试类classProduct{public:~Product(){std::cout<<"Product destroyed\n";}};intmain(){// 1. 构造:接管资源MyUniquePtr<Product>p1(newProduct());// 2. 拷贝:编译失败(已禁用)// MyUniquePtr<Product> p2 = p1;// 3. 移动:合法,转移所有权MyUniquePtr<Product>p2=std::move(p1);// p1 已被置空,p2 持有资源// 4. 函数返回:自动移动(临时对象)autocreateProduct(){returnMyUniquePtr<Product>(newProduct());}MyUniquePtr<Product>p3=createProduct();// 合法,移动构造return0;// p3、p2 析构,自动释放资源}

总结

  1. unique_ptr的核心实现逻辑:禁用拷贝 + 实现移动 + RAII 自动释放
  2. 移动语义是unique_ptr实现“独占且可转移”的关键:通过右值引用接管资源,同时置空原对象,保证所有权唯一;
  3. 自定义类要发挥移动语义价值,需像unique_ptr这样:实现移动构造/赋值,在其中完成“资源转移+原对象置空”,避免浅拷贝问题。

这也是为什么说“移动语义是unique_ptr的灵魂”——没有移动语义,就无法在保证“独占性”的前提下实现所有权转移,只能像老旧的auto_ptr那样靠“劫持拷贝语义”模拟,极易出错。

http://www.jsqmd.com/news/327254/

相关文章:

  • 社会网络仿真软件:NodeXL_(16).案例研究:NodeXL在公共政策分析中的应用
  • 基于微信小程序的云浮市特色农产品交易的设计与实现_4k747azt_zl007
  • 社会网络仿真软件:NodeXL_(15).NodeXL与其他工具的集成
  • app加密账户隐藏的是金额
  • 基于协同过滤算法的运动场馆服务平台设计与实现_93kv0nhb
  • 50.腐烂的橘子
  • 社会网络仿真软件:NodeXL_(15).案例研究:NodeXL在商业分析中的应用
  • 基于微信小程序的智慧社区娱乐服务管理平台_jm78648u
  • 深入解析:中文社交媒体情感分析实战:基于B站评论的机器学习与深度学习对比
  • 基于微信小程序的健康管理系统的设计与实现_387dlt2q
  • 【中大企业选择源码部署商城系统】
  • 基于微信小程序的驾校预约管理系统的小程序_u6pho7j3
  • 基于微信小程序的生猪养殖信息化管理系统_50z6uv9o
  • LangChain 实战:RunnableWithMessageHistory 深度详解
  • 应用层协议HTTP(1) - 教程
  • javaWeb从入门到进阶(SpringBoot原理及bean对象)
  • Flink 弹性伸缩(Elastic Scaling)Adaptive Scheduler、Reactive Mode 与外部资源声明
  • Excel CELL函数深度解析:从基础信息提取到条件格式高阶应用
  • 用 PyTorch 实现 LLM-JEPA:不预测 token,预测嵌入
  • 上海计算机学会2026年1月月赛C++丙组T5 打扫
  • 上海计算机学会2026年1月月赛C++丙组T4 分形十字
  • HarmonyOS 上,App、游戏、PC 能共用架构吗?
  • 没有文档模型,HarmonyOS PC 应用会发生什么?
  • Ai元人文构想:认知共生宣言——迈向人机协作新文明
  • 从注册到跑通项目:体验了飞算JavaAI专业版的“真·无限”开发自由
  • 爬虫-今日头条我的收藏-反爬虫分析(六)
  • 0x3f 第48天 面向实习的八股背诵第五天 + 堆一题 背了JUC的题,java.util.Concurrency
  • 深度学习篇---瓶颈结构残差块
  • 基于微信小程序的医疗器械预定系统_053btbe2
  • Go项目 工具栈选型