新闻中心

C++ shared_ptr如何使用_C++智能指针原理与循环引用解决

2025-12-02
浏览次数:
返回列表
shared_ptr通过引用计数管理对象生命周期,使用make_shared创建更高效,循环引用需用weak_ptr解决。

c++ shared_ptr如何使用_c++智能指针原理与循环引用解决

在C++中,shared_ptr 是一种智能指针,用于自动管理动态分配对象的生命周期。它通过引用计数机制确保多个指针可以共享同一个对象,当最后一个 shared_ptr 被销毁时,对象会自动被释放,避免内存泄漏。

shared_ptr 基本用法

要使用 shared_ptr,需包含头文件 。创建 shared_ptr 的推荐方式是使用 make_shared,它更高效且异常安全。

示例:

#include <memory>
#include <iostream>

struct MyClass {
    int value;
    MyClass(int v) : value(v) {
        std::cout << "构造: " << value << "\n";
    }
    ~MyClass() {
        std::cout << "析构: " << value << "\n";
    }
};

int main() {
    auto ptr1 = std::make_shared<MyClass>(42);
    {
        auto ptr2 = ptr1; // 引用计数 +1
        std::cout << "当前引用计数: " << ptr1.use_count() << "\n"; // 输出 2
    } // ptr2 离开作用域,引用计数 -1
    std::cout << "ptr2 销毁后引用计数: " << ptr1.use_count() << "\n"; // 输出 1
} // ptr1 销毁,对象自动释放

关键点:

  • 引用计数:每个 shared_ptr 实例增加引用计数,销毁时减一。
  • 自动释放:计数为0时,自动调用 delete。
  • 线程安全:多个线程可同时持有 shared_ptr,但指向同一对象的访问仍需同步。

智能指针原理简析

shared_ptr 内部包含两个关键部分:

  • 指向对象的指针
  • 控制块(control block):保存引用计数、弱引用计数和删除器等信息

每次拷贝 shared_ptr,引用计数加1;析构时减1。控制块通常在第一次创建 shared_ptr 时分配(如 make_shared 或 shared_ptr 构造函数)。

make_shared 的优势在于将对象和控制块一起分配,减少内存碎片并提升性能。

循环引用问题与 weak_ptr 解决方案

当两个对象互相持有对方的 shared_ptr 时,引用计数无法降为0,导致内存泄漏。这就是循环引用

Voicepods Voicepods

Voicepods是一个在线文本转语音平台,允许用户在30秒内将任何书面文本转换为音频文件。

Voicepods 142 查看详情 Voicepods

示例:

struct Node;
using NodePtr = std::shared_ptr<Node>;

struct Node {
    int data;
    NodePtr parent;
    NodePtr child;

    Node(int d) : data(d) {
        std::cout << "Node " << data << " 构造\n";
    }
    ~Node() {
        std::cout << "Node " << data << " 析构\n";
    }
};

void test_cycle() {
    auto n1 = std::make_shared<Node>(1);
    auto n2 = std::make_shared<Node>(2);
    n1->child = n2;
    n2->parent = n1; // 循环引用!
} // 函数结束,n1 和 n2 的引用计数仍为1,不会析构

解决方法:使用 weak_ptr 打破循环。weak_ptr 不增加引用计数,只“观察”对象是否存在。

修改后的代码:

struct Node {
    int data;
    std::weak_ptr<Node> parent; // 使用 weak_ptr
    NodePtr child;

    Node(int d) : data(d) { }
    ~Node() {
        std::cout << "Node " << data << " 析构\n";
    }
};

访问 weak_ptr 时需先 lock() 获取临时 shared_ptr:

auto p = n2->parent.lock();
if (p) {
    std::cout << "Parent data: " << p->data << "\n";
}

这样,当 n1 和 n2 离开作用域,引用计数正确归零,对象被释放。

基本上就这些。shared_ptr 简化了内存管理,但要注意避免循环引用。合理使用 weak_ptr 可有效打破循环,确保资源及时释放。

以上就是C++ shared_ptr如何使用_C++智能指针原理与循环引用解决的详细内容,更多请关注其它相关文章!


# 是一个  # 静安区优化推广网站建设  # 苏州安严seo  # 福州一般seo优化  # 静海区网站建设企业  # seo标题优化方法  # 平罗网站网络推广  # 抖音营销推广怎么做系统  # 安顺独立网站建设要点  # 关键词优化软件gh迅捷云排名  # 驻马店专业优化网站  # 相关文章  # 这就是  # 是一种  # c++智能指针  # 安全策略  # 多线程  # 尼克  # 多个  # 如何使用  # red  # 作用域  # 解决方法  # stream  # ios  # c++  # ai  # node 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 在React函数组件中利用原生HTML5进行邮箱地址验证  Win11怎么开启省电模式_Win11电池节电模式自动开启  魅族17怎样用浏览器译外语网页_iPhone魅族17浏览器译外语网页【即时翻译】  提升Kafka消费者健壮性:会话超时处理与消息处理语义  如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】  J*aScript异步迭代器_j*ascript异步遍历  漫蛙漫画网页端入口 漫蛙2官方正版漫画站点  学习通网页版快速入口 学习通官网网页版直接打开  学习通在线学习平台 学习通网页版直接进入课程中心  星露谷物语官网入口 星露谷物语游戏官网入口  TypeScript/J*aScript:高效查找数组中首个唯一ID对象  Go语言JSON解析深度指南:动态访问与结构体映射实践  QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道  小米Civi 4录制视频过暗_小米Civi 4亮度优化  Win11怎么隐藏桌面图标 Win11一键隐藏所有桌面元素及恢复显示  php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】  腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录  在FastAPI中利用lifespan与依赖注入高效管理Redis连接池  谷歌google账号怎么注册账号 谷歌账号注册官方流程  MAC怎么安装Homebrew包管理器_MAC为开发者和高级用户安装命令行工具  c++ dfs和bfs代码 c++深度广度优先搜索算法  电脑IP地址怎么查 查看本机IP地址的几种方法  如何在Promise链中有效终止错误处理后的执行  Python字典中优雅地迭代剩余元素的方法  KFC游戏互动怎么赢取优惠券_KFC线上游戏活动参与与优惠代码赢取教程  NetBeans Ant项目:自动化将资源文件复制到dist目录的教程  Shopware订单对象中获取产品自定义字段的正确方法  TikTok网页版直接登录 TikTok网页端官方平台入口  深入理解Go语言中Map值与方法接收器的交互:为什么需要临时变量  如何在J*a中使用Locale处理多语言环境  苹果手机指南针不准怎么校准 传感器校准方法详解【建议收藏】  邮政快递单号查询入口 邮政快递物流信息在线查询入口  谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示  精准捕获:如何在页面中监听除特定元素外的所有点击事件  Surface怎么安装系统 微软Surface Pro U盘重装win11教程  QQ邮箱网页版登录入口 QQ邮箱官方在线使用平台  微信客户端如何收红包_微信客户端接收红包使用教程  顺丰国际快递查询 国际件官方查询入口  虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画  如何更改在 Excel 中打开超链接时的默认浏览器  夸克浏览器图书入口 夸克手机浏览器阅读入口  品牌机怎么重装系统 联想/戴尔/惠普笔记本恢复出厂系统教程  打开就能玩的植物大战僵尸 植物大战僵尸网页版传送门  word中如何让数字纵向排列_Word数字纵向排列方法  漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口  AO3官方在线访问地址 Archive of Our Own最新镜像合集  Steam官网入口直达 Steam注册及登录步骤  Angular中父组件异步更新子组件复选框状态的实践指南  必由学在线入口 必由学网页版快速登录入口  J*aScript实现动态背景色下的文本与按钮颜色自适应调整 

搜索