C++解决智能指针交叉引用问题

智能指针的交叉引用问题,是如下代码发生的问题,导致的结果是对象无法析构,资源无法释放,问题严重!

class B;
class A
{
public:
    A(){cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}
    shared_ptr<B> _ptrb;
};

class B
{
public:
    B(){cout<<"B()"<<endl;}
    ~B(){cout<<"~B()"<<endl;}
    shared_ptr<A> _ptra;
};
int main(int argc, char* argv[])
{
    shared_ptr<A> ptra(new A());
    shared_ptr<B> ptrb(new B());

    ptra->_ptrb = ptrb;
    ptrb->_ptra = ptra;

    return 0;
}

显而易见,类A中有一个指向类B的shared_ptr强类型智能指针,类B中有一个指向类A的shared_ ptr强类型智能指针

此时,有两个强智能指针指向了对象A,对象A的引用计数为2。也有两个强智能指针指向了对象B,对象B的引用计数为2。对象A与对象B的关系如图所示 :
智能指针1

当主函数return返回后,对象A的引用计数减一变为1,对象B的引用计数减一变为1,此时因为引用计数不为0,所以不能析构对象释放内存,程序结束造成内存泄漏。

解决方法:将类A和类B中的shared_ptr强智能指针都换成weak_ptr弱智能指针。我们在使用强弱智能指针的时候,有一个规定,就是创建对象的时候,持有它的强智能指针,当其他地方想使用这个对象的时候,应该持有该对象的弱智能指针。

class B;
class A
{
public:
    A(){cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}
    weak_ptr<B> _ptrb; //其他地方持有对象的弱智能指针
};

class B
{
public:
    B(){cout<<"B()"<<endl;}
    ~B(){cout<<"~B()"<<endl;}
    weak_ptr<A> _ptra; //其他地方持有对象的弱智能指针
};

int main(int argc, char* argv[])
{
    shared_ptr<A> ptra(new A()); //创建对象时持有强智能指针
    shared_ptr<B> ptrb(new B()); //创建对象时持有强智能指针

    ptra->_ptrb = ptrb;
    ptrb->_ptra = ptra;

    return 0;
}

weak_ptr弱智能指针,虽然有引用计数,但实际上它并不增加计数,而是只观察对象的引用计数,weak_ptr的引用计数指的是有多少个weak_ptr在观察同一个shared_ptr。而shared_ptr强智能指针的引用计数是对资源的引用计数所以此时对象A的引用计数只为1,对象B的引用计数也只为1。此时对象A与对象B的关系如图所示 :
智能指针2
当主函数return返回后,对象A的引用计数减一变为0,所以正常析构对象A;对象B的引用计数减一变为0,所以正常析构对象B,此时不会造成内存泄漏。

总结:
(1)创建对象的时候用shared_ptr强智能指针,别的地方一律持有weak_ptr弱智能指针,否则析构顺序有可能出现错误。
(2)当通过弱智能指针访问对象时,需要先进行lock提升操作,提升成功,证明对象还存在,再通过强智能指针访问对象。

参考:http://blog.csdn.net/qq_36953135/article/details/76998104

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值