当前位置:

首页 > 编程开发 > unique\_ptr、shared\_ptr、weak\_ptr区别详解

unique\_ptr、shared\_ptr、weak\_ptr区别详解

智能指针是C++中自动管理内存的工具,主要包括unique_ptr、shared_ptr和weak_ptr。1.unique_ptr用于独占所有权,不可复制,转移需用std::move,销毁时自动删除对象;2.shared_ptr允许多个指针共享同一对象,通过引用计数管理生命周期,但需注意循环引用问题;3.weak_ptr作为弱引用不增加引用计数,用于解决循环引用及实现缓存等场景。合理选择智能指针可避免内存泄漏并提升效率。

本文目录

    智能指针是C++中自动管理内存的工具,主要包括unique_ptr、shared_ptr和weak_ptr。1. unique_ptr用于独占所有权,不可复制,转移需用std::move,销毁时自动删除对象;2. shared_ptr允许多个指针共享同一对象,通过引用计数管理生命周期,但需注意循环引用问题;3. weak_ptr作为弱引用不增加引用计数,用于解决循环引用及实现缓存等场景。合理选择智能指针可避免内存泄漏并提升效率。

    现代C++中的智能指针有哪些区别 unique_ptr shared_ptr weak_ptr对比

    智能指针,说白了,就是帮你自动管理内存的指针。现代 C++ 里,它们已经是标配了,unique_ptr、shared_ptr 和 weak_ptr,各有各的用处和侧重点,用错了地方,轻则效率打折,重则内存泄漏。

    现代C++中的智能指针有哪些区别 unique_ptr shared_ptr weak_ptr对比

    unique_ptr、shared_ptr、weak_ptr 就像是内存管理战场上的三员大将,各有千秋,用对了地方才能发挥最大威力。

    现代C++中的智能指针有哪些区别 unique_ptr shared_ptr weak_ptr对比

    解决方案

    首先,unique_ptr,顾名思义,它所指向的对象只能被一个 unique_ptr 拥有。这意味着,所有权是独占的,不能简单地复制。当 unique_ptr 销毁时,它所指向的对象也会被自动删除。这避免了忘记 delete 造成的内存泄漏。

    #include 
    #include 
    
    class MyClass {
    public:
        MyClass(int value) : value_(value) {
            std::cout << "MyClass constructed with value: " << value_ << std::endl;
        }
        ~MyClass() {
            std::cout << "MyClass destructed with value: " << value_ << std::endl;
        }
    
        int getValue() const { return value_; }
    
    private:
        int value_;
    };
    
    
    int main() {
        // 创建一个 unique_ptr,指向一个 MyClass 对象
        std::unique_ptr ptr1 = std::make_unique(10);
        std::cout << "Value: " << ptr1->getValue() << std::endl;
    
        // 尝试复制 unique_ptr 会导致编译错误
        // std::unique_ptr ptr2 = ptr1; // 错误:unique_ptr 不可复制
    
        // 可以使用 std::move 转移所有权
        std::unique_ptr ptr2 = std::move(ptr1);
        std::cout << "Value: " << ptr2->getValue() << std::endl;
    
        // 现在 ptr1 不再拥有对象,访问它会导致未定义行为
        // std::cout << "Value: " << ptr1->getValue() << std::endl; // 避免这样做
    
        // ptr2 在 main 函数结束时会被销毁,MyClass 对象也会被销毁
        return 0;
    }

    shared_ptr 则允许多个指针指向同一个对象,它使用引用计数来跟踪有多少个 shared_ptr 指向该对象。只有当引用计数降为零时,对象才会被删除。这使得在多个对象之间共享所有权变得非常方便。但是,循环引用会导致内存泄漏,需要小心。

    现代C++中的智能指针有哪些区别 unique_ptr shared_ptr weak_ptr对比
    #include 
    #include 
    
    class MyClass {
    public:
        MyClass(int value) : value_(value) {
            std::cout << "MyClass constructed with value: " << value_ << std::endl;
        }
        ~MyClass() {
            std::cout << "MyClass destructed with value: " << value_ << std::endl;
        }
    
        int getValue() const { return value_; }
    
    private:
        int value_;
    };
    
    int main() {
        // 创建一个 shared_ptr,指向一个 MyClass 对象
        std::shared_ptr ptr1 = std::make_shared(20);
        std::cout << "Value: " << ptr1->getValue() << std::endl;
        std::cout << "Reference count: " << ptr1.use_count() << std::endl;
    
        // 复制 shared_ptr,引用计数增加
        std::shared_ptr ptr2 = ptr1;
        std::cout << "Value: " << ptr2->getValue() << std::endl;
        std::cout << "Reference count: " << ptr1.use_count() << std::endl;
        std::cout << "Reference count: " << ptr2.use_count() << std::endl;
    
        // ptr1 和 ptr2 都指向同一个对象,该对象在 main 函数结束时会被销毁一次
        return 0;
    }

    最后,weak_ptr 是一种“弱引用”,它指向由 shared_ptr 管理的对象,但不增加引用计数。weak_ptr 可以用来观察对象是否仍然存在,而不会阻止对象被删除。这对于解决循环引用问题非常有用。

    #include 
    #include 
    
    class MyClass {
    public:
        MyClass(int value) : value_(value) {
            std::cout << "MyClass constructed with value: " << value_ << std::endl;
        }
        ~MyClass() {
            std::cout << "MyClass destructed with value: " << value_ << std::endl;
        }
    
        int getValue() const { return value_; }
    
    private:
        int value_;
    };
    
    int main() {
        // 创建一个 shared_ptr,指向一个 MyClass 对象
        std::shared_ptr sharedPtr = std::make_shared(30);
        std::cout << "Shared pointer value: " << sharedPtr->getValue() << std::endl;
        std::cout << "Shared pointer reference count: " << sharedPtr.use_count() << std::endl;
    
        // 创建一个 weak_ptr,指向同一个 MyClass 对象
        std::weak_ptr weakPtr = sharedPtr;
        std::cout << "Weak pointer expired: " << weakPtr.expired() << std::endl;
    
        // 可以使用 weak_ptr 的 lock() 方法获取一个 shared_ptr
        std::shared_ptr lockedPtr = weakPtr.lock();
        if (lockedPtr) {
            std::cout << "Locked pointer value: " << lockedPtr->getValue() << std::endl;
            std::cout << "Shared pointer reference count: " << sharedPtr.use_count() << std::endl;
        } else {
            std::cout << "Weak pointer is expired." << std::endl;
        }
    
        // 释放 shared_ptr
        sharedPtr.reset();
        std::cout << "Shared pointer reference count: " << sharedPtr.use_count() << std::endl;
        std::cout << "Weak pointer expired: " << weakPtr.expired() << std::endl;
    
        // 再次尝试使用 weak_ptr 的 lock() 方法
        lockedPtr = weakPtr.lock();
        if (lockedPtr) {
            std::cout << "Locked pointer value: " << lockedPtr->getValue() << std::endl;
        } else {
            std::cout << "Weak pointer is expired." << std::endl;
        }
    
        return 0;
    }

    何时使用 unique_ptr?

    当你希望对象的所有权是唯一的,并且在 unique_ptr 销毁时自动删除对象时,使用 unique_ptr。例如,在工厂函数中返回新创建的对象,或者在类中拥有一个独占的资源。

    shared_ptr 如何避免循环引用导致的内存泄漏?

    循环引用是指两个或多个对象互相持有 shared_ptr,导致引用计数永远不为零,对象永远无法被删除。解决循环引用的方法是使用 weak_ptr。一个对象持有另一个对象的 weak_ptr,而不是 shared_ptr,这样就不会增加引用计数。当需要访问对象时,可以使用 weak_ptr::lock() 方法获取一个 shared_ptr,如果对象已经被删除,lock() 方法会返回 nullptr。

    weak_ptr 的使用场景有哪些?

    除了解决循环引用问题,weak_ptr 还可以用于缓存。例如,一个缓存对象可以使用 weak_ptr 来持有缓存项,当缓存项不再被其他对象使用时,缓存对象会自动释放缓存项。还可以用于观察者模式,观察者可以使用 weak_ptr 来持有被观察者的引用,当被观察者被删除时,观察者可以自动取消订阅。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 C++
    相关文章 更多
    C++动态数组初始化怎么写?常用语句与代码示例
    C++动态数组初始化怎么写?常用语句与代码示例

    深入解析C++中动态数组的初始化机制,涵盖new操作符的不同用法、基本类型与类对象的初始化差异,以及为何在现代C++开发中应优先使用std::vector。

    C++类构造与析构函数详解
    C++类构造与析构函数详解

    C++类构造与析构函数详解 C++这门语言,可以说是从C语言这棵大树上衍生出的高级果实,如今的应用普及度有目共睹。作为一种静态类型的通用编程语言,它厉害的地方在于融合了多种编程哲学——无论是传统的面向过程,还是主流的面向对象,乃至数据抽象、泛型编程这些高级概念,它都能很好地支持。正因为这份卓越的扩展

    C++中std::upper
    C++中std::upper

    C++中std::upper_bound用法解析 在C++标准模板库(STL)的算法工具箱里,upper_bound() 绝对算得上是一把精准的“探针”。它的核心任务很明确:在一个已经排好序的区间 [first, last) 内,帮你快速定位到第一个**严格大于**指定值 value 的那个元素。这

    C++常对象与成员解析
    C++常对象与成员解析

    C++中“常”概念全景解析:从对象、成员到指针与引用 在C++的世界里,“常量性”是一个强大的保障机制。它不仅仅是一个const关键字那么简单,而是构建健壮、安全程序的重要基石。今天,我们就来系统梳理一下围绕“常”的一系列概念:常成员、常对象、常指针与常引用。理解它们,是写出高质量C++代码的关键一

    c++如何将结构体写入SQLite数据库_对象关系映射方案【进阶】
    c++如何将结构体写入SQLite数据库_对象关系映射方案【进阶】

    直接用SQLiteCAPI绑定结构体需要手动处理字段展平与顺序对齐,ORM库虽省代码但存在隐式行为风险。小项目建议原生绑定,中大型项目可搭配编译期校验使用轻量ORM。绑定std::string需传指针与长度,注意生命周期;浮点字段比较需设误差范围。

    什么是编程,学习编程的意义是?
    什么是编程,学习编程的意义是?

    编程是编写程序指令,让设备按意图运行,常用Python、C等语言或Scratch图形化编程。学习编程能跟上科技时代,锻炼自学与解决问题能力,提升逻辑思维,代表行动力,推动事物前进。各司其职,编程者尽本分。

    编程是门艺术_是编程艺术吗?
    编程是门艺术_是编程艺术吗?

    编程被争论是否为艺术。从定义看,编程是技能表达,但并非所有编程都是应用开发。写代码如音乐、文章,有独特风格。好代码需耐心与逻辑能力。编程是艺术,但应用开发不等同于编程艺术。

    【编程的感受】
    【编程的感受】

    很多人提起编程,总觉得这是一门“不起眼”的学问——不就是写写代码嘛,能有多深?但真走进去了才会发现,编程里头的门道,远比表面看上去要丰富得多。 学习编程的过程中,最容易卡住的往往是那些基础语法。就拿那个常见的 for 循环来说吧,刚开始时怎么都绕不过弯来:为什么这么写能循环?循环条件到底怎么控制?一

    对于懂得编程的人来说,编程对你来说有什么乐趣?编程大概是什么感觉?
    对于懂得编程的人来说,编程对你来说有什么乐趣?编程大概是什么感觉?

    解决编程问题后的痛快、完成作品的成就感、获取知识的满足感,以及用代码实现简化生活的惊喜与踏实,这些是编程独有的乐趣,只有真正写代码的人才能体会其中的酸甜苦辣、惊喜与满足,令人回味无穷。

    趣味编程:少儿编程思维的启蒙之旅
    趣味编程:少儿编程思维的启蒙之旅

    Scratch图形化编程以拖拽积木块方式启蒙少儿编程思维,无需记忆代码语法。通过素材库、即时反馈和社区协作,帮助孩子在创作中理解顺序执行、条件判断等核心概念,锻炼逻辑、创造力和问题解决能力。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。