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 pShare = make_shared();

	pShare.reset();


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

	shared_ptr pShareB = pShare;
	

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

运行结果

shared_ptr&&weak_ptr_第1张图片

使用注意事项:

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


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

	pShare.reset();


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

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

 shared_ptr&&weak_ptr_第2张图片

 2)避免循环引用

weak_ptr

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

循环引用

#include 
#include 
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 pB) {m_pB = pB;}
private:
	shared_ptr 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 pA) { m_pA = pA; }
private:
	shared_ptr m_pA;
};


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

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

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

#include 
#include 
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 pB) {m_pB = pB;}
private:
	weak_ptr 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 pA) { m_pA = pA; }
private:
	weak_ptr m_pA;
};


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

shared_ptr&&weak_ptr_第3张图片

此时,析构函数被调用。

实现差异

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

shared_ptr&&weak_ptr_第4张图片

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

shared_ptr&&weak_ptr_第5张图片

当shared_ptr被赋值后,_Uses会加1

shared_ptr&&weak_ptr_第6张图片

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

 

 

 

你可能感兴趣的:(C++随笔,boost,c++)