shared_ptr,weak_ptr,unique_ptr

1.shared_ptr 互相引用会出现资源不释放的问题,造成内存泄漏。

比如这段代码:

class C2;
class C1 {
private:
	std::shared_ptr<C2> _c2;  
public:
	void setC2(std::shared_ptr<C2> c2) {
		_c2 = c2;
	}

	~C1() {
		std::cout << "kill c1\n";
	}
};

class C2 {
private:
	std::shared_ptr<C1> _c1;
public:
	void setC1(std::shared_ptr<C1> c1) {
		_c1 = c1;
	}
	~C2() {
		std::cout << "kill c2\n";
	}
};

void testptr()
{
	std::shared_ptr<C1> c1(new C1());
	std::shared_ptr<C2> c2(new C2());
	if (c1 && c2)
	{
		c1->setC2(c2);
		c2->setC1(c1);
	}

这个问题并不直观。

换一种思考方式,假设在某一个时刻,智能指针中的C1对象被销毁,那么c1._c2才会销毁,这个时候引用了C2类型的shared_ptr引用计数才会有可能变成0(按照我们的例子,就是在这个时刻引用计数变成0),智能指针中的C2对象才会被销毁,而也只有在智能指针中的C2对象被销毁时,引用了C1类型的shared_ptr引用计数才会变成0,这个时候才会去析构智能指针中的C1对象,所以分析到这里,我们会发想刚才的假设不会发生。这样就形成了一个互相牵制的死结。

两种解决方案:

1.如果确实需要按照testptr函数中的方式调用,则根据业务理清两个类的关系,哪个类生命周期依赖另一个,将命长的那个类作为shared_ptr作为命短的类的成员,将命短的那个类作为wead_ptr作为命长的类的成员,并在使用的时候,通过wead_ptr::lock()得到shared_ptr,保证使用范围内,命短的成员不会挂掉。

2.避免testptr函数中的调用方式,如果业务允许,可以考虑:

		c1->setC2(c2);
		c2->setC1(c1_1);//std::shared_ptr<C1> c1_1(new C1());
weak_ptr并不像shared_ptr一样维护引用计数,所以不会存在像shared_ptr的问题,但是引入的新问题是,如果使用weak_ptr,即便是你定义了一个变量,这个变量的存活期也并不能由你来掌控,所以是一个弱控制的指针,只有在调用lock拿到一个shared_ptr的这段时间里,是你可以确定你的变量是真实存活着的。并且weak_ptr并不能单独使用,只能配合shared_ptr或者其他weak_ptr一同使用,来解决shared_ptr互相引用的问题。

unique_ptr旨在替代auto_ptr,因为auto_ptr的copy导致的被copy对象变成null的问题,整体用法就是提供对内存对象的独占访问,并且使用release显式移交所有权。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值