参考文档:https://blog.csdn.net/jcq521045349/article/details/88957222
弱引用的智能指针weak_ptr是用来监视shared_ptr的,不会使引用计数加一,它不管理shared_ptr内部的指针,主要是为了监视shared_ptr的生命周期,更像是shared_ptr的一个助手。
weak_ptr没有重载运算符*和->,因为它不共享指针,不能操作资源,主要是为了通过shared_ptr获得资源的监测权,它的构造不会增加引用计数,它的析构不会减少引用计数,纯粹只是作为一个旁观者来监视shared_ptr中关离得资源是否存在。
weak_ptr还可以用来返回this指针和解决循环引用的问题。weak_ptr 的一个重要用途是“打破循环引用”,即解决 shared_ptr (引用计数)在循环引用中的“无能”。
使用弱引用wak_ptr来解决智能指针内存泄漏的例子
template <class T>
class WeakedPtr;
template<class T>
class SharePtr
{
public:
friend class WeakedPtr<T>;
SharePtr(T* ptr = NULL) :_ptr(ptr), _refCount(new int(1))
{}
~SharePtr()
{
if (--(*_refCount) == 0)
{
delete _ptr;
delete _refCount;
}
}
//s1(s2)
SharePtr(const SharePtr<T>& sp) :_ptr(sp._ptr), _refCount(sp._refCount)
{
(*_refCount)++;
}
//sp1 = sp2
SharePtr<T>& operator=(SharePtr<T>& sp)
{
if (_ptr != sp._ptr)
{
if (--(*_refCount) == 0)
{
delete _ptr;
delete _refCount;
}
_ptr = sp._ptr;
_refCount = sp._refCount;
(*_refCount)++;
}
return *this;
}
//为了像指针一样才进行*\->的重载
//->的重载
T* operator->()
{
return _ptr;
}
//*的重载
T& operator*()
{
return *_ptr;
}
//查看引用计数的多少
int UseCount()
{
return *_refCount;
}
private:
T* _ptr;
int* _refCount;//一块空间有一个指针
};
//解决了循环引用问题
template <class T>
class WeakedPtr
{
public:
WeakedPtr() :_ptr(NULL)
{}
WeakedPtr(const SharePtr<T>& sp)
:_ptr(sp._ptr)
{}
WeakedPtr<T>& operator=(const SharePtr<T>&sp)
{
_ptr = sp._ptr;
return *this;
}
T& operator* ()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};
struct ListNode
{
int _data;
WeakedPtr<ListNode> _next;
WeakedPtr<ListNode> _prev;
~ListNode()
{
cout << "~ListNode" << endl;
}
};
void testSharePtr()
{
//SharePtr<int> sp1(new int(1));
//SharePtr<int> sp2(sp1);
SharePtr<ListNode> cur(new ListNode);
SharePtr<ListNode> next(new ListNode);
cout << cur.UseCount() << endl;
cout << next.UseCount() << endl;
}
C++11智能指针内存泄漏查找方法
可以在XCODE中先查看是否存在内存泄漏,如果有就一步一步查。
1.析构函数打断点,查看退出场景时某类的析构函数是否调用。
2.强引用的地方查看是否有循环引用。如果有,使用weak_ptr
如可以,最好保证只有一个最必要的地方对其持有强引用并管理。
3.查看基类是否是虚析构函数。 如果不是就改正。
4.lambda表达式[pointer]中的引用指针是永久持有,所以不要随意的添加变量。
这里有特殊情况,如果是异步操作,局部变量的智能指针是没有被引用的,所以在异步的回调中智能指针已被释放,所以请注意保证指针的引用计数。
原文地址:https://blog.csdn.net/qq_36474990/article/details/78748895