首页 > 编程语言 >什么是 C++ 中的智能指针?有哪些类型的智能指针?

什么是 C++ 中的智能指针?有哪些类型的智能指针?

时间:2024-11-22 18:45:21浏览次数:3  
标签:std C++ 智能 引用 shared unique ptr 指针

智能指针的定义

在 C++ 中,智能指针是一种类模板,用于管理动态分配的内存。它的主要目的是自动管理内存的生命周期,避免手动释放内存时可能出现的错误,如内存泄漏(忘记释放内存)和悬空指针(访问已释放的内存)。智能指针通过重载*(解引用运算符)和->(成员访问运算符)等运算符,使得它在行为上类似于普通指针,但又具有自动内存管理的功能。

例如,在没有智能指针的情况下,使用普通指针分配内存如下:

int* ptr = new int;
// 使用ptr
delete ptr;  // 需要手动释放内存,如果忘记就会导致内存泄漏

而智能指针可以自动处理内存的释放,减少这种错误的发生。

智能指针的类型

std::unique_ptr独占所有权:

std::unique_ptr是一种独占式智能指针,它所管理的对象只能有一个unique_ptr与之关联。这意味着当一个unique_ptr拥有一个对象的所有权时,其他unique_ptr不能同时拥有该对象。

示例:

#include <memory>
int main() {
    std::unique_ptr<int> ptr1 = std::make_unique<int>(5);
    // std::unique_ptr<int> ptr2 = ptr1;  // 这是错误的,不能复制unique_ptr
    std::unique_ptr<int> ptr3 = std::move(ptr1);  // 通过移动语义转移所有权
    return 0;
}

资源所有权转移:

它通过移动语义(std::move函数)来转移资源的所有权。当一个unique_ptr被移动到另一个unique_ptr后,原来的unique_ptr就不再拥有该资源,其内部指针变为nullptr。这种机制保证了对象的独占性,并且符合 C++ 的零开销原则,因为没有额外的引用计数等开销。

std::shared_ptr共享所有权:

std::shared_ptr实现了共享式的所有权管理。多个shared_ptr可以同时指向同一个对象,对象的生命周期会一直持续到最后一个指向它的shared_ptr被销毁。

引用计数机制:

它内部使用引用计数来记录有多少个shared_ptr指向同一个对象。每当一个新的shared_ptr指向该对象时,引用计数加 1;当一个shared_ptr被销毁(例如超出作用域)时,引用计数减 1。当引用计数变为 0 时,所管理的对象会被自动删除。

#include <memory>
int main() {
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10);
    std::shared_ptr<int> ptr2 = ptr1;  // 共享所有权,引用计数变为2
    return 0; 
}
// 当main函数结束,ptr1和ptr2都超出作用域,引用计数减为0,对象被自动删除

std::weak_ptr弱引用:

std::weak_ptr是一种弱引用智能指针,它主要用于解决std::shared_ptr可能出现的循环引用问题。weak_ptr不控制对象的生命周期,它只是对一个由shared_ptr管理的对象的弱引用。

与shared_ptr的关系:weak_ptr可以通过lock函数来获取一个指向相同对象的shared_ptr,如果对象已经被释放(引用计数为 0),则lock函数返回一个空的shared_ptr。

循环引用示例及解决方法:

假设有两个类A和B,它们相互包含shared_ptr成员,可能会导致循环引用

class B;
class A {
public:
    std::shared_ptr<B> b;
    A() {}
    ~A() {}
};
class B {
public:
    std::shared_ptr<A> a;
    B() {}
    ~B() {}
};
int main() {
    std::shared_ptr<A> a = std::make_shared<A>();
    std::shared_ptr<B> b = std::make_shared<B>();
    a->b = b;
    b->a = a;
    // 这里a和b的引用计数都为2,当main函数结束时,它们的引用计数无法减为0,导致内存泄漏,无法调用a,b的析构函数
    // 使用weak_ptr解决
    class B;
    class A {
    public:
        std::weak_ptr<B> b;
        A() {}
        ~A() {}
    };
    class B {
    public:
        std::weak_ptr<A> a;
        B() {}
        ~B() {}
    };
    std::shared_ptr<A> a = std::make_shared<A>();
    std::shared_ptr<B> b = std::make_shared<B>();
    a->b = b;
    b->a = a;
    // 这样就不会出现循环引用导致的内存泄漏问题
    return 0;
}

标签:std,C++,智能,引用,shared,unique,ptr,指针
From: https://blog.csdn.net/2202_75941514/article/details/143980886

相关文章