全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-690-7320

C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能

答案:实现简易 shared_ptr 需定义引用计数控制块,通过构造、拷贝、赋值和析构操作管理资源;1. 使用 int* 动态记录引用计数,多个指针共享同一块内存;2. 拷贝时递增计数,析构或赋值时调用 release 函数递减,为 0 则 delete 资源;3. 支持解引用、get、use_count 等接口;4. 示例验证了构造、作用域析构、赋值等场景下引用计数正确变化;5. 关键点包括独立分配计数、自赋值保护、reset 正确释放旧资源;6. 局限性有非线程安全、无自定义删除器、未优化内存布局,生产环境需改进。

c++如何实现一个智能指针_手动实现c++ shared_ptr的引用计数功能

实现一个简易的 shared_ptr 智能指针,核心是模拟引用计数机制,确保多个指针共享同一块内存时,只有最后一个指针释放时才真正 delete 资源。下面是一个手动实现的基本版本,包含构造、拷贝、赋值和析构等关键操作。

1. 定义引用计数控制块

我们需要一个额外的结构体来管理原始指针和引用计数,这个结构体被所有共享该对象的智能指针共用。

template <typename T>
class SharedPtr {
private:
    T* ptr;                    // 指向实际数据的指针
    int* ref_count;            // 指向引用计数的指针
<pre class='brush:php;toolbar:false;'>void release() {
    if (ref_count && --(*ref_count) == 0) {
        delete ptr;
        delete ref_count;
        ptr = nullptr;
        ref_count = nullptr;
    }
}

public: // 构造函数:接管原始指针 explicit SharedPtr(T* p = nullptr) : ptr(p), ref_count(nullptr) { if (ptr) { ref_count = new int(1); } }

// 拷贝构造函数
SharedPtr(const SharedPtr& other) : ptr(other.ptr), ref_count(other.ref_count) {
    if (ref_count) {
        ++(*ref_count);
    }
}

// 拷贝赋值运算符
SharedPtr& operator=(const SharedPtr& other) {
    if (this != &other) {
        release();  // 释放当前资源
        ptr = other.ptr;
        ref_count = other.ref_count;
        if (ref_count) {
            ++(*ref_count);
        }
    }
    return *this;
}

// 析构函数
~SharedPtr() {
    release();
}

// 解引用
T& operator*() const { return *ptr; }
T* operator->() const { return ptr; }

// 获取原始指针
T* get() const { return ptr; }

// 获取引用计数(调试用)
int use_count() const { return ref_count ? *ref_count : 0; }

// 判断是否唯一拥有
bool unique() const { return use_count() == 1; }

// 重置指针
void reset(T* p = nullptr) {
    release();
    ptr = p;
    if (ptr) {
        ref_count = new int(1);
    } else {
        ref_count = nullptr;
    }
}

};

2. 使用示例

测试我们实现的 SharedPtr 是否正确管理引用计数。

#include <iostream>
<p>struct MyClass {
int value;
MyClass(int v) : value(v) { std::cout << "MyClass(" << v << ") created\n"; }
~MyClass() { std::cout << "MyClass destroyed\n"; }
};</p><p>int main() {
SharedPtr<MyClass> sp1(new MyClass(42));
std::cout << "use count: " << sp1.use_count() << "\n";</p><pre class='brush:php;toolbar:false;'>{
    SharedPtr<MyClass> sp2 = sp1;
    std::cout << "use count after copy: " << sp1.use_count() << "\n";
} // sp2 析构,引用计数减一

std::cout << "use count after sp2 destroyed: " << sp1.use_count() << "\n";

SharedPtr<MyClass> sp3;
sp3 = sp1; // 赋值测试
std::cout << "use count after assignment: " << sp1.use_count() << "\n";

return 0;

}

Seede AI Seede AI

AI 驱动的设计工具

Seede AI 713 查看详情 Seede AI

3. 关键点说明

这个简易实现展示了 shared_ptr 的核心思想:

  • 引用计数独立分配:使用 int* 动态分配计数,确保多个实例共享同一个计数值。
  • release 函数:在析构和赋值时调用,负责递减计数并清理资源。
  • 自赋值保护:赋值前检查 this != &other,避免错误释放。
  • reset 方法:允许智能指针切换到新对象,并正确处理旧资源。

4. 局限性与改进方向

此实现是教学性质的简化版,生产环境的 shared_ptr 还需考虑:

  • 线程安全:多线程下引用计数应使用原子操作(如 std::atomic)。
  • 支持自定义删除器(deleter)。
  • weak_ptr 配合避免循环引用。
  • 性能优化:比如控制块与对象一起分配,减少内存碎片。

基本上就这些。理解引用计数的生命周期管理,是掌握智能指针的关键。

以上就是C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能的详细内容,更多请关注其它相关文章!


# 相关文章  # 采药通网站推广好做吗  # 东营企业seo服务  # 企通网站建设  # 广州网站方案建设书  # 沈阳网站seo排名公司推荐  # 长治网站推广排名  # 专注福州seo价位多少  # 名优营销推广咨询电话  # 游戏公众号怎么营销推广  # 网站建设与博客  # 解决问题  # 中文网  # ai  # 数独  # 是一个  # 如何用  # 自定义  # 多线程  # 多个  # 如何实现  # red  # 作用域  # stream  # ios  # c++ 


相关文章: 海棠电脑版入口_通过电脑访问海棠官网阅读  Lar*el Migration:重命名列后添加新列的正确操作顺序  如何更改在 Excel 中打开超链接时的默认浏览器  UC浏览器网页版登录入口官网 电脑版网址入口  《噬血代码2》新预告片发布 展示游戏剧情  抖音隐秘迷城小游戏入口_ 抖音冒险解谜小游戏秒玩  MinIO大规模对象列表性能瓶颈深度解析与外部元数据管理策略  J*a中实现Go语言select通道多路复用机制  CSS布局:解决全屏元素100%尺寸与外边距导致的页面溢出问题  百度浏览器字体显示异常偏小_百度浏览器字体渲染修复方案  在WordPress中通过REST API获取BasicAuth保护的远程文章  支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  C#中解析不规范的HTML为XML 常见的坑与解决办法  React Router 嵌套组件中 URL 重定向问题的解决方案  如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构  晋江读书网页版在线登录 晋江读书电脑版官网  凉拌黄瓜怎么拌更入味 凉拌黄瓜简单家常做法  理解J*aScript Promise的微任务队列与执行顺序  将PCM16音频转换为W*并编码为Base64:浏览器环境下的手动处理指南  印象笔记如何设提醒任务防漏执行_印象笔记设提醒任务防漏执行【任务提醒】  在python-socketio事件处理器中安全访问Flask应用上下文  Lar*el头像管理:图片缩放与旧文件删除的最佳实践  Excel组合图表怎么做 Excel创建柱状图与折线组合图教程【图表】  qq游戏免费畅玩入口_qq游戏电脑版快速启动  在J*a中如何实现对象克隆避免共享数据_对象克隆安全实践指南  HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全  小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口  LocoySpider如何部署到云服务器_LocoySpider云部署的远程配置  企业名称高精度匹配:N-gram方法在结构相似性分析中的应用  蛙漫正版漫画平台入口_蛙漫免费阅读全站漫画资源  vivo云服务网页版登录 怎么登录vivo云服务网页版  腾讯视频怎么举报不良内容_腾讯视频内容举报流程与违规信息处理方法  邮政快递单号查询入口 邮政快递物流信息在线查询入口  C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果  win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】  Animex动漫社网入口地址 Animex动漫社网正版在线入口  win11如何卸载Windows更新补丁 Win11解决更新导致系统不稳定的问题【修复】  必由学网页版入口 必由学官方平台直接访问  神庙逃亡小游戏在线玩 神庙逃亡小游戏入口  Golang如何优雅处理error_Golang error处理最佳实践总结  苹果手机指南针不准怎么校准 传感器校准方法详解【建议收藏】  星露谷物语官网入口 星露谷物语游戏官网入口  如何在低配置电脑上搭建轻量级J*a环境_占用更小的环境选择技巧  Python多版本共存与虚拟环境管理深度指南  网易大神账号申诉需要多久_网易大神账号申诉流程说明  中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】  在WordPress中通过REST API访问受BasicAuth保护的站点内容  4399体育竞技小游戏_4399小游戏赛事入口  实现分段式页面滚动导航:CSS与J*aScript教程 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。