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

shared_ptr和weak_ptr原理

template <typename T>
struct control_block {
    size_t use_count;  // 强引用计数
    size_t weak_count; // 弱引用计数
    T* ptr;            // 指向托管对象的裸指针
    std::function<void(T*)> deleter;  // 删除器,删对象用的

    // 构造函数初始化
    control_block(T* p, std::function<void(T*)> d)
        : use_count(1), weak_count(0), ptr(p), deleter(d) {}
};



template <typename T>
class shared_ptr {
private:
    control_block<T>* ctrl_block;  // 控制块

public:
    shared_ptr(T* p, std::function<void(T*)> deleter= std::default_delete<T>())
        : ctrl_block(new control_block<T>(p, deleter)) {}


    ~shared_ptr() {
        // 销毁控制块并删除对象
        if (--ctrl_block->use_count == 0) {
            ctrl_block->deleter(ctrl_block->ptr);  // 删除对象
            if (ctrl_block->weak_count == 0) {
                delete ctrl_block;  // 删除控制块
            }
        }
    }

    // 拷贝构造函数,增加引用计数
    shared_ptr(const shared_ptr& other)
        : ctrl_block(other.ctrl_block) {
        ++ctrl_block->use_count;
    }

      
    shared_ptr(const weak_ptr& other)
        : ctrl_block(other.ctrl_block) {
         ++ctrl_block->use_count;
    }

    // 获取托管对象
    T* get() const { return ctrl_block->ptr; }

    // 返回控制块
    control_block<T>* get_control_block() const { return ctrl_block; }
};

template <typename T>
class weak_ptr {
private:
    control_block<T>* ctrl_block;  // 控制块

public:
    weak_ptr() : ctrl_block(nullptr) {}

    weak_ptr(const shared_ptr<T>& sp) : ctrl_block(sp.get_control_block()) {
        ++ctrl_block->weak_count;  // 增加弱引用计数
    }

    ~weak_ptr() {
        if (ctrl_block && --ctrl_block->weak_count == 0 && ctrl_block->use_count == 0) {
            delete ctrl_block;  // 控制块被销毁
        }
    }

    // 尝试获取 shared_ptr
    shared_ptr<T> lock() const {
        if (ctrl_block && ctrl_block->use_count > 0) {
            return shared_ptr<T>(*this);  // 转换为 shared_ptr
        }
        return shared_ptr<T>();  // 返回空的 shared_ptr
    }
};

1.为什么用对象指针去创建两个智能指针他们的计数会分开计数?因为有两个控制块,各管理各的

2.强引用计数用来维持对象的生命周期,弱引用计数用来解决循环引用的问题

http://www.dtcms.com/a/111630.html

相关文章:

  • TortoiseGit多账号切换配置
  • Ubuntu服务器 无法正常启动redis
  • cmake(12):在 CMake 的 CMakeLists.txt 中也可以进行流程控制,也就是说可以像写 shell 脚本那样进行条件判断和循环。
  • ubantu22.04中搭建地图开发环境(qt5.15.2 + osg3.7.0 + osgearth3.7.1 + osgqt)
  • 自然科学基金项目答辩ppt设计制作美化案例模板下载
  • 机器学习学习笔记
  • Promise 详细说明、常用方法
  • 【备考高项】模拟预测题(一)综合知识及答案详解
  • C++_模板初阶
  • transform
  • VirtualBox安装FnOS
  • pat学习笔记
  • JavaScript学习19-事件类型之鼠标事件
  • 【2019】【论文笔记】混合石墨烯等离子体光栅在THz下增强非线——
  • 配置文件、Spring日志
  • Java基础 4.4
  • 论文阅读Diffusion Autoencoders: Toward a Meaningful and Decodable Representation
  • Dagster系列教程:快速掌握数据资产定义
  • 数据库系统概述 | 第二章课后习题答案
  • 计算机系统---CPU
  • 嵌入式系统应用-拓展-相关开发软件说明
  • 常见的微信个人号二次开发功能
  • Unity:平滑输入(Input.GetAxis)
  • 【Cursor】切换主题
  • JS API
  • 【软考中级软件设计师】数据表示:原码、反码、补码、移码、浮点数
  • sward V1.0.8版本发布,全面支持各种附件上传预览
  • 初识数据结构——算法效率的“两面性”:时间与空间复杂度全解析
  • yolov12检测 聚类轨迹运动速度
  • 与总社团联合会合作啦