c++shared_ptr用weak_ptr打破循环引用(C++类相关)

智能指针循环引用:

当两个shared_ptr智能指针调用两个相互调用的类的时候依然会存在内存泄露的情况,因为只有到user_count=0的时候才能释放该智能指针相互都在等待对方释放资源:`

class Parent;
typedef std::shared_ptr<Parent> ParentPtr;
class Child{
	public:
	ParentPtr father;
	~Child();
	Child;
};
typedef std::shared_ptr<Child> ChildPtr;

class Parent{
	public:
		ChildPtr son;
		~Parent();
		Parent();
};
Child::Child(){std::count<<"hello child\n";}
Parent::Parent(){std::cout<<"hello parent\n";}
Child::~Child(){std::cout<<"bye child\n";}
Parent::~Parent(){std::cout<<"bye parent\n";}
void testParentAndChild(){
	ParentPtr p(new Parent());
	ChildPtr c(new Child());
	p->son = c; //c.use_count () == 2 and p.use_count() == 1
	c->father = p;	//c.use_count() == 2 p.use_count() == 2
}

用weak_ptr可以打破智能指针循环引用所出现的问题。

当外部有share_ptr在管理weak_ptr资源时则该指针是有效的,否则无效用lock()来控制

void sharedPtrWithWeakPtr() {
	ObjectPtr obj(new Object(1));
	typedef std::weak_ptr<Object> WeakObjectPtr;
	WeakObjectPtr weakObj2;
	WeakObjectPtr weakObj(obj);
	WeakObjectPtr weakObj3(obj);
	std::cout << "obj use count is " << obj.use_count() << std::endl; // 1
	{
		auto p = weakObj.lock(); // auto === ObjectPtr
		if(p) {
			std::cout << p.unique() << std::endl; // false p.use_count() >= 2
			// do what you want to do
		} else {
		}
	}
	obj.reset(new Object(2));
	{
		auto p = weakObj.lock();
		if(p) {
			assert(false);
			// do what you want to do
		} else {
		}
	}
	weakObj = obj;
	if(weakObj.expired()) {
	} else {
	}
}

如果调用reset()后再调用lock()永远只会false,如果reset一个new资源原有的也会false

再=obj时weak_ptr指针就会又有效,可以用weak_ptr的expired()函数来判断该指针是否有管理资源

obj.reset();
auto p = weakObj.lock();
if(p){
	asset(false);
	//do what you want to do
}else{
}
obj.reset(new Object(2));
auto p = weakObj.lock();
if(p){
	asset(false);
	//do what you want to do
}else{
}
weakObj = obj;
if(weakObj.expired()){
}else{
}

只要让shared_ptr循环引用中打破一环,shared_ptr就能发挥它应有的作用,下例程序可正常运行:

class Parent;
typedef std::weak_ptr<Parent> ParentPtr;
class Child{
	public:
	ParentPtr father;
	~Child();
	Child;
};
typedef std::shared_ptr<Child> ChildPtr;

class Parent{
	public:
		ChildPtr son;
		~Parent();
		Parent();
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值