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标准的核心特性
相关推荐
郝学胜_神的一滴21 小时前
CMake 034:生成器表达式:解耦构建时序、精简分支逻辑的终极利器
c++·cmake
见过夏天2 天前
C++ 基础入门完全指南
c++
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK3 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境4 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境4 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴5 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境7 天前
C++ 的Eigen 库全解析
c++
卷无止境7 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴7 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake