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

实现一个简易的 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
AI 驱动的设计工具
713
查看详情
3. 关键点说明
这个简易实现展示了 shared_ptr 的核心思想:
- 引用计数独立分配:使用 int* 动态分配计数,确保多个实例共享同一个计数值。
- release 函数:在析构和赋值时调用,负责递减计数并清理资源。
- 自赋值保护:赋值前检查 this != &other,避免错误释放。
- reset 方法:允许智能指针切换到新对象,并正确处理旧资源。
4. 局限性与改进方向
此实现是教学性质的简化版,生产环境的 shared_ptr 还需考虑:
- 线程安全:多线程下引用计数应使用原子操作(如 std::atomic)。
- 支持自定义删除器(deleter)。
- weak_ptr 配合避免循环引用。
- 性能优化:比如控制块与对象一起分配,减少内存碎片。
基本上就这些。理解引用计数的生命周期管理,是掌握智能指针的关键。
以上就是C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能的详细内容,更多请关注其它相关文章!
# c++
# ios
# stream
# ai
# 采药通网站推广好做吗
# 东营企业seo服务
# 企通网站建设
# 广州网站方案建设书
# 沈阳网站seo排名公司推荐
# 长治网站推广排名
# 专注福州seo价位多少
# 名优营销推广咨询电话
# 游戏公众号怎么营销推广
# 网站建设与博客
# 解决问题
# 中文网
# 相关文章
# 数独
# 是一个
# 如何用
# 自定义
# 多线程
# 多个
# 如何实现
# red
# 作用域
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Python实时数据流中的动态最值查找策略
Excel Power Pivot如何处理XML数据源 构建高级数据模型
微信网页版官方快速登录入口 微信网页版网页版账号直达
163邮箱注册官网 免费申请163个人邮箱
蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址
汽水音乐在线版入口_汽水音乐网页播放手册
如何在低配置电脑上搭建轻量级J*a环境_占用更小的环境选择技巧
sublime怎么进行远程开发编辑_配置rsub/rmate实现sublime编辑服务器文件
yy漫画网页版官方入口_yy漫画官网登录页面链接
打开就能玩的植物大战僵尸 植物大战僵尸网页版传送门
如何有效阻止外部脚本意外修改内联样式的高度属性
C++如何操作大型数据集_使用C++流式处理(Streaming)技术避免一次性加载大文件
c++项目目录结构应该如何组织_c++工程化项目结构规范
解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误
C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果
C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程
C#使用XPath查询节点时出错? 常见语法错误与调试技巧
如何在更新Composer依赖后自动运行测试_使用post-update-cmd钩子触发PHPUnit
如何使用spryker/configurable-bundles-products-resource-relationship模块解决复杂产品捆绑关系难题
Composer的 "check-platform-reqs" 命令有什么用_在部署前检查生产环境是否满足Composer依赖需求
内存疯狂猛猛涨价:主板销量直接腰斩!
必由学网页版入口 必由学官方平台直接访问
内存检查:在VS Code中调试C++时的内存视图
J*a中实现Go语言select通道多路复用机制
4399免费游戏网址入口 4399小游戏免费入口点开即玩
steam官方网页快速访问 steam账号注册全流程
零跑汽车11月交付量达70327台 实现连续9个月正增长
如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构
火狐浏览器占用内存高卡顿怎么办 火狐浏览器性能优化设置技巧
将HTML Canvas内容转换为可上传的图像文件(File对象)
利用5118提升短视频内容效果_5118短视频关键词优化方法
利用Bokeh CustomJS动态控制DataTable列可见性
优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题
拼多多购物车商品数量无法修改如何处理 拼多多购物车操作优化方法
KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明
蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版
Golang并发任务中错误如何聚合_Golang goroutine error收集方式
在Qt QML中通过Python字典动态更新TextEdit内容的教程
C++指针和引用有什么区别_C++内存管理核心概念深度解析
MAC怎么让Dock栏只显示当前运行的应用_MAC终端命令实现极简Dock栏
在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验
LINQ to XML为何解析失败? 深入理解C# XDocument的异常处理
我的世界官方游戏入口 我的世界官网平台直达链接
提升Kafka消费者健壮性:会话超时处理与消息处理语义
实现全屏滚动与导航点:专业教程
Python中高效访问嵌套字典与列表中的键值对
拼多多视频播放卡顿如何处理 拼多多视频播放优化技巧
PHP中SSG-WSG API的AES加密实践:正确使用初始化向量
初次安装JDK时环境变量如何正确配置_J*A_HOME与PATH设置规则讲解
win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】


2025-12-01
浏览次数:次
返回列表