智能指针,shared_ptr和weak_ptr

智能指针shared_ptr

在使用原始指针的时候,经常出现如下情形,A指针和B指针同时指向堆上的一个对象object,在运行的过程中,同过A指针使用delete把这个对象object释放了,而且也把A指向了null,但是这个时候B指针就成了空悬指针,如果对B进行操作,程序就会崩溃。

针对这种情况的一个解决办法就是,在A、B指针和object对象之间再加一层代理指针proxy,A和B都指向proxy,proxy代理指针指向实际的对象object。那么当对A进行delete操作的时候,通过proxy指针,把object对象释放,然后proxy指向0。这样,再使用B去通过proxy访问对象的时候,发现代理指针指向空,也就知道对象已经被释放了。但是这里还是有一个问题,什么时候释放代理指针?

对于这个问题的解决办法就是,再代理指针数据里面再加一个计数,每增加一个指向object的指针时,计数+1,没一个指针delete的时候,计数-1.当计数=0的时候,释放代理指针。这也就是智能指针的思路,使用引用计数来决定是否对指针指向的内容进行销毁操作。

 

循环引用

智能指针虽然好用,但是它也存在一个问题就是,循环引用,可以看如下代码段:

#include <iostream>

#include <memory>

#include <iostream>

class B;

class A{

public:

    A(){}

    ~A(){

        std::cout<<"A destruct"<<std::endl;

    }

    void setPtr(std::shared_ptr<B> _ptr){

        ptr = _ptr;

    }

private:

    std::shared_ptr<B> ptr;

};

 

class B{

public:

    B(){}

    ~B(){

        std::cout<<"B destruct"<<std::endl;

    }

    void setPtr(std::shared_ptr<A> _ptr){

        ptr = _ptr;

    }

 

private:

    std::shared_ptr<A> ptr;

};

 

int main()

{

    if(1)

    {

        std::shared_ptr<A> p1(new A());

        std::shared_ptr<B> p2(new B());

 

        p1->setPtr(p2);

        p2->setPtr(p1);

    }

    return 0;

}

在运行的时候发现并不会执行到A和B的析构函数中去,这是因为出现循环引用了。在p1的指针指向了p2,所以p2要释放必须p1中的指针先释放掉,同理,p2中的指针指向了p1,p1需要释放的话,必须p2中的指针先释放,这就导致两个指针指向的对象始终得不到释放。

weak_ptr

弱指针与shared_ptr的区别在于weak_ptr对象引用资源时不会增加引用计数,需要对weak_ptr指向的对象进行访问时,只需要使用lock()返回一个shared_ptr,这个shared_ptr可以访问到指向的对象,并且在这个shared_ptr作用域内,对象不会被释放掉。

把上述例子中的A类中的shared_ptr<B>换成weak_ptr<B>就不会出现循环引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值