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

独立简化版SharedPtr

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

文章目录

    • 调整说明
    • 完整独立实现代码
      • 1. 头文件与引用计数结构体
      • 2. 独立版 SharedPtr 实现
      • 3. 测试代码(单独测试 SharedPtr)
    • 核心代码关键点解释
      • 1. 引用计数规则(核心)
      • 2. 关键函数说明
      • 3. 编译运行
      • 4. 预期输出
      • 总结

我完全理解你的需求,现在彻底剥离 WeakPtr 相关的所有代码,仅保留独立、完整可运行的SharedPtr实现,移除弱引用计数、友元类关联等无关逻辑,代码结构更简洁,方便你单独学习和阅读。

调整说明

  1. 移除weak_ref弱引用计数,引用计数结构体仅保留强引用计数
  2. 删除WeakPtr整个类,清理所有关联代码
  3. 简化资源释放逻辑:强引用计数归 0 时,直接释放托管对象 + 计数对象
  4. 保留shared_ptr核心功能:构造/析构、拷贝/移动、重置、交换、运算符重载
  5. 代码可独立编译运行,无任何外部依赖

完整独立实现代码

1. 头文件与引用计数结构体

仅保留强引用计数,无弱引用相关逻辑

#include<iostream>#include<utility>// std::swap#include<string>// 测试用// 仅保留强引用计数,专为 SharedPtr 服务structRefCount{intstrong_ref;// 强引用计数:标记共享资源的 SharedPtr 数量// 构造函数:初始无引用RefCount():strong_ref(0){}// 快捷构造:创建新托管对象时,计数初始为1explicitRefCount(ints):strong_ref(s){}};

2. 独立版 SharedPtr 实现

移除所有WeakPtr关联代码,核心逻辑不变,更精简

// 共享式智能指针(独立实现,无weak_ptr依赖)template<typenameT>classSharedPtr{public:// 空构造:默认空指针,无计数对象SharedPtr():ptr_(nullptr),ref_count_(nullptr){}// 有参构造:托管原始指针,explicit 禁止隐式转换explicitSharedPtr(T*p):ptr_(p){if(ptr_){// 托管有效对象,创建计数对象,强引用初始为1ref_count_=newRefCount(1);}else{ref_count_=nullptr;}}// 析构函数:自动释放资源~SharedPtr(){release();}// 拷贝构造:共享资源,强引用计数 +1SharedPtr(constSharedPtr&other){ptr_=other.ptr_;ref_count_=other.ref_count_;// 计数对象存在时,增加引用计数if(ref_count_){ref_count_->strong_ref++;}}// 移动构造:转移所有权,不修改计数,原指针置空SharedPtr(SharedPtr&&other)noexcept{ptr_=other.ptr_;ref_count_=other.ref_count_;// 清空原对象,避免重复释放other.ptr_=nullptr;other.ref_count_=nullptr;}// 拷贝赋值:先释放当前资源,再共享新资源SharedPtr&operator=(constSharedPtr&other){if(this!=&other){// 防止自赋值release();// 释放当前持有的资源// 共享新资源ptr_=other.ptr_;ref_count_=other.ref_count_;if(ref_count_){ref_count_->strong_ref++;}}return*this;}// 移动赋值:转移所有权,高效无计数修改SharedPtr&operator=(SharedPtr&&other)noexcept{if(this!=&other){release();// 接管资源ptr_=other.ptr_;ref_count_=other.ref_count_;// 清空原对象other.ptr_=nullptr;other.ref_count_=nullptr;}return*this;}// 重载解引用运算符:访问托管对象T&operator*()const{return*ptr_;}// 重载箭头运算符:访问对象成员T*operator->()const{returnptr_;}// 获取原始指针T*get()const{returnptr_;}// 获取当前强引用计数intuse_count()const{returnref_count_?ref_count_->strong_ref:0;}// 重置:释放当前资源,托管新对象voidreset(T*p=nullptr){release();// 先释放旧资源ptr_=p;if(ptr_){ref_count_=newRefCount(1);}else{ref_count_=nullptr;}}// 交换两个 SharedPtr 的资源voidswap(SharedPtr&other)noexcept{std::swap(ptr_,other.ptr_);std::swap(ref_count_,other.ref_count_);}private:T*ptr_;// 指向托管资源的原始指针RefCount*ref_count_;// 共享的引用计数对象指针// 私有辅助函数:统一处理资源释放逻辑voidrelease(){if(ref_count_){// 强引用计数减1ref_count_->strong_ref--;// 计数为0:无指针共享资源,释放内存if(ref_count_->strong_ref==0){deleteptr_;// 释放托管的业务对象deleteref_count_;// 释放引用计数对象}// 清空当前对象指针,防止野指针ptr_=nullptr;ref_count_=nullptr;}}};

3. 测试代码(单独测试 SharedPtr)

沿用之前的测试逻辑,适配独立版实现

// 单独测试 SharedPtrvoidtest_shared_ptr(){std::cout<<"===== 独立版 SharedPtr 测试 ====="<<std::endl;// 行1:构造sp1,托管字符串Hello,计数=1SharedPtr<std::string>sp1(newstd::string("Hello"));std::cout<<*sp1<<",强引用计数:"<<sp1.use_count()<<std::endl;// 行2:拷贝构造sp2,共享资源,计数+1=2SharedPtr<std::string>sp2=sp1;std::cout<<*sp2<<",强引用计数:"<<sp1.use_count()<<std::endl;// 行3:sp1重置,托管新字符串World,原资源计数-1=1sp1.reset(newstd::string("World"));std::cout<<*sp1<<",强引用计数:"<<sp1.use_count()<<std::endl;std::cout<<*sp2<<",强引用计数:"<<sp2.use_count()<<std::endl;// 行4:移动构造sp3,转移sp1所有权,计数不变SharedPtr<std::string>sp3=std::move(sp1);if(sp1.get()==nullptr){std::cout<<"sp1移动后为空"<<std::endl;}std::cout<<*sp3<<",强引用计数:"<<sp3.use_count()<<std::endl;}intmain(){test_shared_ptr();return0;}

核心代码关键点解释

1. 引用计数规则(核心)

  • 创建新托管对象:强引用计数= 1
  • 拷贝构造/赋值:共享资源,强引用计数+1
  • 析构/reset/赋值:放弃资源,强引用计数-1
  • 计数归0同时释放托管对象 + 计数对象,杜绝内存泄漏

2. 关键函数说明

  1. release():私有辅助函数,统一封装资源释放逻辑,避免代码冗余
  2. 移动语义:仅转移指针所有权,不修改计数,比拷贝更高效
  3. reset():主动释放当前资源,可重新托管新对象,支持空指针重置

3. 编译运行

直接使用 C++ 编译器编译运行即可(支持 C++11 及以上标准):

g++ main.cpp -o shared_ptr_test -std=c++11 ./shared_ptr_test

4. 预期输出

===== 独立版 SharedPtr 测试 ===== Hello,强引用计数:1 Hello,强引用计数:2 World,强引用计数:1 Hello,强引用计数:1 sp1移动后为空 World,强引用计数:1

总结

  1. 这是无任何依赖的独立SharedPtr实现,移除了所有weak_ptr相关代码,结构更清晰
  2. 完整保留标准shared_ptr核心功能:引用计数、拷贝共享、移动转移、自动释放内存
  3. 资源释放逻辑简化:强引用计数为 0 时,直接释放所有堆内存,无额外逻辑
  4. 代码可直接编译运行,适合单独学习共享式智能指针的底层原理
http://www.jsqmd.com/news/337437/

相关文章:

  • Taro+React+ts开发类似抖音的视频播放功能
  • SPI总线全攻略:从以太网组网、大容量Flash存储到AirLink高速通信
  • 省时省力,CAN总线一站式开发指南
  • 亲测好用10个降AIGC网站 千笔帮你降AI率
  • 新手入门:阿里云OSS存储完整使用指南(从配置到实操)
  • 救命神器!AI论文网站 千笔·专业论文写作工具 VS 笔捷Ai,自考写论文必备!
  • 2026年NMN品牌技术实力排名:基于核心机制与实证数据的深度盘点 - 速递信息
  • 盘点2026年专业眼镜店连锁品牌,康视怡配镜服务性价比高靠谱吗 - 工业品牌热点
  • GO!开源UART短信转发器【无需焊接+不耗流量】
  • 食品包装机械远程运维管理系统方案
  • MCP 协议爆火背后:AI 应用开发正在经历 USB 时刻
  • 探讨2026年行业排名前十的跨境电商财税合规代办机构 - mypinpai
  • 导师推荐10个降AI率平台,千笔·专业降AI率智能体解决论文AIGC检测难题
  • Linux 命令:diff3
  • 必收藏!未来5年程序员最优发展方向,认准AI大模型准没错
  • 卡西欧品牌代理价格对比 全国性价比高的卡西欧代理服务 - myqiye
  • DeepSeek V4代码生成实战:3步用AI模型搭建你的第一个智能脚本
  • 德国inne品牌深度解析:守护全龄营养,凭创新活动领跑行业 - 速递信息
  • Java程序员必学的Agent开发:一篇掌握大模型智能体核心概念,建议收藏
  • 2026跨境电商财税合规代办机构推荐哪家,结合费用来看选择更准 - mypinpai
  • 收藏备用|AI浪潮下,传统程序员转型AI工程师全指南(小白也能看懂)
  • 说说武汉财税合规政府补助核算公司价格多少钱 - myqiye
  • Linux 命令:patch
  • linux防火墙核心命令 - 教程
  • 智源多模态大模型登Nature,生成式人工智能路线统一到自回归
  • 中小企业的“零门槛数字化”救星——无需IT团队,3天搭建适配业务的招聘流程
  • 2026最新西南管材选购风向标:PE管/ HDPE管/复合管/ PVC管/波纹管五大实力品牌推荐 - 深度智识库
  • 聊聊2026年性价比高的地产开发运营商,哪个口碑好值得选 - 工业设备
  • 微信立减金还可以这样用!团团收回收变现的最佳选择 - 团团收购物卡回收
  • 分享实力强的防火堵料实体厂家,费用怎么收费 - 工业品网