c语言编程笔录

首页 > C语言 > c语言

c语言

C++中智能指针最常用的shared_ptr和unique_ptr

更新时间:2023-08-12

背景介绍

智能指针是C++中解决内存管理问题的一种技术。传统的指针在使用过程中容易引起内存泄漏和悬挂指针等问题,而智能指针通过自动内存释放的机制提供了更加可靠和安全的内存管理方式。

C++中最常用的智能指针是shared_ptr和unique_ptr。shared_ptr是一种共享所有权的指针,可以被多个指针共同拥有,而unique_ptr是一种独占所有权的指针,只能被一个指针拥有。它们都是从C++11标准引入的,为了解决传统指针的缺陷。

shared_ptr的特点和用途

shared_ptr是基于引用计数的智能指针,它通过记录当前指向对象的引用计数,在所有引用计数归零时自动释放对象内存。因此,shared_ptr可以被多个指针共享,每次拷贝会增加引用计数,每次析构会减少引用计数。当引用计数为零时,shared_ptr会自动释放内存。

#include 

void func()
{
    std::shared_ptr sp1(new int(10));  // 创建shared_ptr,引用计数为1

    {
        std::shared_ptr sp2 = sp1;  // 使用拷贝构造函数,引用计数加1
        std::cout << "sp1 count: " << sp1.use_count() << std::endl;
        std::cout << "sp2 count: " << sp2.use_count() << std::endl;
    }  // 出作用域,sp2析构,引用计数减1

    std::cout << "sp1 count: " << sp1.use_count() << std::endl;
}  // 函数结束,sp1析构,引用计数减1,内存释放

shared_ptr的主要用途是在需要多个指针共享同一块内存的场景中,例如在函数传参、数据结构中使用。它提供了一种方便和安全的方式管理动态内存,避免了忘记释放内存或者释放已释放内存的问题。

unique_ptr的特点和用途

unique_ptr是基于“独占所有权”的智能指针,它提供了一种精确和高效的内存管理方式。与shared_ptr不同,unique_ptr不能被多个指针共享,只能通过移动语义和转移所有权的方式进行传递。

#include 

void func()
{
    std::unique_ptr up1(new int(10));  // 创建unique_ptr

    {
        std::unique_ptr up2 = std::move(up1);  // 使用std::move函数转移所有权
        // std::unique_ptr up2(up1);  // 错误!unique_ptr不能直接进行拷贝
        std::cout << "up1: " << (up1 == nullptr) << std::endl;  // 输出1,up1已经无效
        std::cout << "up2: " << (up2 != nullptr) << std::endl;  // 输出1,up2有效
    }  // 出作用域,up2析构,内存被自动释放

    std::cout << "up1: " << (up1 == nullptr) << std::endl;  // 输出1,up1仍然无效
}  // 函数结束,up1析构,内存仍然无效

unique_ptr主要用于需要独占所有权、不需要共享所有权的场景。它的设计目标是高效的内存管理和资源释放,通过禁止直接拷贝来保证只有一个指针能够操纵这块内存,提高了代码的可读性和安全性。

总结

shared_ptr和unique_ptr是C++中常用的智能指针,它们旨在解决传统指针的内存管理问题。shared_ptr提供了一种共享所有权的方式,可以被多个指针共同拥有,通过引用计数的机制自动释放内存。unique_ptr提供了一种独占所有权的方式,通过移动语义和转移所有权的方式来使用,保证只有一个指针能够操纵内存。

使用智能指针可以大大简化C++程序的内存管理和资源释放,避免了内存泄漏和悬挂指针等一系列问题。在实际开发中,合理选择和使用智能指针将提高代码的质量和可维护性。