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标准的核心特性
相关推荐
似水明俊德23 分钟前
02-C#.Net-反射-面试题
开发语言·面试·职场和发展·c#·.net
Thera7771 小时前
C++ 高性能时间轮定时器:从单例设计到 Linux timerfd 深度优化
linux·开发语言·c++
炘爚2 小时前
C语言(文件操作)
c语言·开发语言
阿蒙Amon2 小时前
C#常用类库-详解SerialPort
开发语言·c#
凸头2 小时前
CompletableFuture 与 Future 对比与实战示例
java·开发语言
wuqingshun3141592 小时前
线程安全需要保证几个基本特征
java·开发语言·jvm
君义_noip2 小时前
信息学奥赛一本通 1952:【10NOIP普及组】三国游戏 | 洛谷 P1199 [NOIP 2010 普及组] 三国游戏
c++·信息学奥赛·csp-s
Moksha2622 小时前
5G、VoNR基本概念
开发语言·5g·php
jzlhll1233 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin
W.D.小糊涂3 小时前
gpu服务器安装windows+ubuntu24.04双系统
c语言·开发语言·数据库