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标准的核心特性
相关推荐
灰子学技术4 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
二十雨辰4 小时前
[python]-AI大模型
开发语言·人工智能·python
Yvonne爱编码5 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚5 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂5 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
pas1365 小时前
41-parse的实现原理&有限状态机
开发语言·前端·javascript
琹箐5 小时前
最大堆和最小堆 实现思路
java·开发语言·算法
Monly216 小时前
Java:修改打包配置文件
java·开发语言
我命由我123456 小时前
Android 广播 - 静态注册与动态注册对广播接收器实例创建的影响
android·java·开发语言·java-ee·android studio·android-studio·android runtime
island13146 小时前
CANN ops-nn 算子库深度解析:核心算子(如激活函数、归一化)的数值精度控制与内存高效实现
开发语言·人工智能·神经网络