c++ 智能指针

  • 智能指针是为了解决手动管理动态分配内存的问题。使用RAII(资源获取即初始化)原则,通过在对象的构造函数中分配内存,并在对象的析构函数中释放内存,从而保证资源的正确释放,避免了内存泄漏

std::unique_ptr

  • 管理独占所有权的对象指针,保证在其周期结束时释放内存,智能通过移动语义来转移所有权,不能进行复制,通常用于单个所有者的场景,比如管理动态分配的对象或者资源
std::unique_ptr<int> ptr(new int(42));
std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
  • 这个就是将裸指针进行一个单纯的封装,构造函数和析构函数

std::shared_ptr

  • 允许多个指针共享同一个对象,使用引用计数来追踪有多少个指针指向相同的对象,只有当最后一个std::shared_ptr超出作用域时,内存才会被释放,通常用于共享资源所有权的场景
std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
std::shared_ptr<int> ptr2 = ptr1;
  • shared_ptr需要维护的信息有两部分
    • 指向共享资源的指针
    • 引用计数等共享资源的控制信息——事实上是维护一个指向控制信息的指针
std::shared_ptr<T> sptr1(new T);

在这里插入图片描述

std::shared_ptr<T> sptr2 = sptr1;

在这里插入图片描述

  • 这里看着每个shared_ptr对象和控制信息都指向共享资源,但是有的时候不会指向同一个,但是这里不会指向同一个的情况暂时没看懂

std::weak_ptr

  • 是对std::shared_ptr的一种扩展,允许观察共享对象但不拥有它,不会增加引用计数,因此不会影响对象的声明周期,但是不能访问所观察的对象
  • 主要是和shared_ptr共同使用,但不会增加和减少shared_ptr的引用计数,主要用来获得对应shared_ptr的状态信息
std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
std::weak_ptr<int> weakPtr = sharedPtr;

在这里插入图片描述

  • 当shared_ptr析构并释放共享资源的时候,只要weak_ptr对象还存在,控制块就会保留,weak_ptr可以通过控制块观察对象是否存活

在这里插入图片描述

循环引用问题

  • 智能指针循环引用指的是在使用智能指针时,存在多个智能指针相互引用,形成一个循环的情况,会导致资源无法被正确释放,从而导致内存泄漏
class A;
class B;

class A {
public:
    std::shared_ptr<B> bPtr;
    ~A() {
        std::cout << "A destructor called." << std::endl;
    }
};

class B {
public:
    std::shared_ptr<A> aPtr;
    ~B() {
        std::cout << "B destructor called." << std::endl;
    }
};

int main() {
    std::shared_ptr<A> pa = std::make_shared<A>();
    std::shared_ptr<B> pb = std::make_shared<B>();
    pa->bPtr = pb;
    pb->aPtr = pa;

    return 0;
}

  • 此时两个Object的引用计数都是2,例如A的两个引用是pa,pb->ptrA,这里不能说A的两个引用,但是是表示这个意思
  • 此时线程结束,pa,pb结束,但是引用计数只是变为了1,此时ptrA,ptrB没有被释放。
  • 可以将shared_ptr换成weak_ptr,因为weak_ptr不增加引用计数
  • 上述程序什么也不会输出,因为A B还存在引用计数,因此不会调用对应的析构函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙建钊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值