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时,循环引用时,不会导致析构失败。

本文介绍了C++11中shared_ptr和weak_ptr的使用,包括它们的初始化方式、注意事项、循环引用问题的处理以及两者在内存管理中的作用。重点讲解了如何通过make_shared和weak_ptr避免内存泄漏及循环引用导致的问题。
3万+

被折叠的 条评论
为什么被折叠?



