C++智能指针

在C++中,内存管理一直是个棘手的问题。手动管理内存(new/delete)容易导致内存泄漏悬空指针。智能指针的出现,让内存管理变得安全又简单!

为什么需要智能指针?

cpp 复制代码
// 手动管理内存的陷阱
void foo() {
    int* p = new int(10);
    // 如果这里发生异常或提前return,内存泄漏!
}

智能指针通过自动管理内存,在对象离开作用域时自动释放内存,彻底解决内存泄漏问题。

三种核心智能指针

unique_ptr - 独占所有权

  • 特点 :一个指针只能由一个对象拥有,不能拷贝可以移动

  • 使用场景 :资源独占(如网络连接)

    cpp 复制代码
    #include <memory>
    
    std::unique_ptr<int> create_unique() {
        auto p = std::make_unique<int>(42); // 创建智能指针
        return p; // 可以安全返回(移动语义)
    }
    
    int main() {
        auto p = create_unique();
        std::cout << *p; // 输出 42
        // 离开作用域时自动释放内存
    }

    unique_ptr 保证了资源的唯一所有权,避免了共享导致的释放冲突。

shared_ptr - 共享所有权

  • 特点 :多个指针共享 同一资源,引用计数管理生命周期

  • 使用场景 :需要多个对象共享同一资源(如缓存、单例)

    cpp 复制代码
    #include <memory>
    
    struct Resource {
        ~Resource() { std::cout << "资源释放\n"; }
    };
    
    int main() {
        auto r1 = std::make_shared<Resource>();
        {
            auto r2 = r1; // 引用计数+1
            std::cout << "当前引用计数: " << r1.use_count() << "\n";
        } // r2离开作用域,计数-1
        std::cout << "当前引用计数: " << r1.use_count() << "\n";
        // r1离开作用域时自动释放资源
    }

    use_count() 查看引用计数,当计数为0时自动释放

weak_ptr - 弱引用

  • 特点不增加引用计数 ,解决shared_ptr循环引用问题

  • 使用场景 :观察者模式、缓存等需要避免循环引用的场景

    cpp 复制代码
    #include <memory>
    
    struct Node {
        std::shared_ptr<Node> next;
        std::weak_ptr<Node> prev; // 避免循环引用
    };
    
    int main() {
        auto a = std::make_shared<Node>();
        auto b = std::make_shared<Node>();
        
        a->next = b;
        b->prev = a; // 弱引用,不会增加计数
        
        // 释放时不会因循环引用卡住
        a.reset(); // 释放a,b的next被释放
    }

    通过lock()检查资源是否还有效:

    cpp 复制代码
    if (auto locked = weak_ptr.lock()) {
        // 资源有效,安全使用
    }

    智能指针使用守则

    表格

    指针类型 不能拷贝 能移动 引用计数 适用场景
    unique_ptr 独占资源
    shared_ptr 共享资源
    weak_ptr 避免循环引用

为什么应该优先用智能指针?

  1. 安全:自动管理内存,避免内存泄漏
  2. 简洁:代码更短,逻辑更清晰
  3. 现代C++:是C++11标准的核心特性
相关推荐
2501_944521592 小时前
Flutter for OpenHarmony 微动漫App实战:主题配置实现
android·开发语言·前端·javascript·flutter·ecmascript
MX_93592 小时前
以配置非自定义bean来演示bean的实例化方式
java·开发语言·后端
清酒难咽2 小时前
算法案例之回溯法
c++·经验分享·算法
小王努力学编程2 小时前
LangChain——AI应用开发框架(核心组件2)
linux·服务器·c++·人工智能·python·langchain·信号
2501_944521592 小时前
Flutter for OpenHarmony 微动漫App实战:动漫卡片组件实现
android·开发语言·javascript·flutter·ecmascript
superman超哥2 小时前
派生宏(Derive Macro)的工作原理:编译时元编程的艺术
开发语言·rust·开发工具·编程语言·rust派生宏·derive macro·rust元编程
easyboot2 小时前
C#使用pythonnet简单示例
开发语言·python·c#
晚霞的不甘2 小时前
Flutter 布局核心:构建交互式文档应用
开发语言·javascript·flutter·elasticsearch·正则表达式
少控科技3 小时前
QT新手日记 030
开发语言·qt