shared_ptr&&weak_ptr

shared_ptr

C++11中引入shared_ptr来简化内存的管理,当shared_ptr不再使用时,自动回收内存。

初始化

1)通过 make_shared赋值(推荐的初始化方式)

2)通过reset

3)通过赋值

int main(int argc, char* argv[])
{
	cout << "**************implement an instance by make_shared **************************" << endl;
	shared_ptr<CObject> pShare = make_shared<CObject>();

	pShare.reset();


	cout << "**************implement an instance new **************************" << endl;
	CObject* pTemp = new CObject();
	pShare.reset(pTemp);

	shared_ptr<CObject> pShareB = pShare;
	

	cout << "**************end **************************" << endl;
	return 0;
}

运行结果

使用注意事项:

1)一旦shared_ptr被赋值,不建议直接使用原有指针来操作,一旦原来的指针被delete,shared_ptr再次进行析构时会crash。


int main(int argc, char* argv[])
{
	cout << "**************implement an instance by make_shared **************************" << endl;
	shared_ptr<CObject> pShare = make_shared<CObject>();

	pShare.reset();


	cout << "**************implement an instance new **************************" << endl;
	CObject* pTemp = new CObject();
	pShare.reset(pTemp);

	shared_ptr<CObject> pShareB = pShare;
	
	delete pTemp;
	cout << "**************end **************************" << endl;
	return 0;
}

 

 2)避免循环引用

weak_ptr

为了解决循环引用,C++11也引入了weak_ptr

循环引用

#include <iostream>
#include <memory>
using namespace std;

class CSharedB;
class CSharedA
{
public:
	CSharedA() { cout << "This is construct function of CSharedA." << endl; };
	~CSharedA() { cout << "This is destruct function of CSharedA." << endl; };
	void setShared(shared_ptr<CSharedB> pB) {m_pB = pB;}
private:
	shared_ptr<CSharedB> m_pB;
};

class CSharedB
{
public:
	CSharedB() { cout << "This is construct function of CSharedB." << endl; };
	~CSharedB() { cout << "This is destruct function of CSharedB." << endl; };
	void setShared(shared_ptr<CSharedA> pA) { m_pA = pA; }
private:
	shared_ptr<CSharedA> m_pA;
};


int main(int argc, char* argv[])
{
	cout << "**************implement an instance by make_shared **************************" << endl;
	shared_ptr<CSharedA> pShareA = make_shared<CSharedA>();
	shared_ptr<CSharedB> pShareB = make_shared<CSharedB>();
	pShareA->setShared(pShareB);
	pShareB->setShared(pShareA);
	cout << "**************end **************************" << endl;
	return 0;
}

可以看到两个对象都没有被析构,造成的内存泄露 

如果此时将两个类的成员变量由shared_ptr改成weak_ptr

#include <iostream>
#include <memory>
using namespace std;

class CSharedB;
class CSharedA
{
public:
	CSharedA() { cout << "This is construct function of CSharedA." << endl; };
	~CSharedA() { cout << "This is destruct function of CSharedA." << endl; };
	void setShared(shared_ptr<CSharedB> pB) {m_pB = pB;}
private:
	weak_ptr<CSharedB> m_pB;
};

class CSharedB
{
public:
	CSharedB() { cout << "This is construct function of CSharedB." << endl; };
	~CSharedB() { cout << "This is destruct function of CSharedB." << endl; };
	void setShared(shared_ptr<CSharedA> pA) { m_pA = pA; }
private:
	weak_ptr<CSharedA> m_pA;
};


int main(int argc, char* argv[])
{
	cout << "**************implement an instance by make_shared **************************" << endl;
	shared_ptr<CSharedA> pShareA = make_shared<CSharedA>();
	shared_ptr<CSharedB> pShareB = make_shared<CSharedB>();
	pShareA->setShared(pShareB);
	pShareB->setShared(pShareA);
	cout << "**************end **************************" << endl;
	return 0;
}

此时,析构函数被调用。

实现差异

shared_ptr和weak_ptr实现时有_Uses和_Weaks两个计数器, 当shared_ptr被初始化时, _Uses和_Weaks都会被赋值为1。

当weak_ptr被赋值后,_Weaks会被加1

当shared_ptr被赋值后,_Uses会加1

因为 shared_ptr在初始化后 _Uses和_Weaks都会被赋值为1,也就说weak_ptr的持有者永远不会析构对象,所以采用weak_ptr时,循环引用时,不会导致析构失败。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值