shared

xiaoxiao2021-02-28  117

我们首先通过代码了解一下循环引用的情况 首先是shared_ptr的实现

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<stdlib.h> using namespace std; //共享的智能指针 //使用引用计数 template <typename T> class SharedPtr { public: SharedPtr(T *p = NULL)//构造函数 :_p(p) ,_pCount(NULL)//不可以在此处初始化为1,如果p为NULL { if(NULL != _p) { _pCount = new int(1); } } SharedPtr(const SharedPtr& sp)//拷贝构造函数 :_p(sp._p) ,_pCount(sp._pCount) { if(NULL != _pCount)//注意_pCount为NULL的情况,此时不能解引用,不用++ { ++(*_pCount); } } SharedPtr& operator=(const SharedPtr& sp) { if(_p != sp._p)//注意自身赋值,有时候两个不同的对象但里面的的指针指向 //相同不能用(this != &sp)判断出来 { if(NULL != _pCount)//被复制的对象本身为空//就没有为引用计数开辟空间 { if(0 == --(*_pCount))//被赋值的对象自己管理一段空间,需要释放 { delete _p; delete _pCount; _p = NULL; _pCount = NULL; } } _p = sp._p;//和其他对象共同管理 _pCount = sp._pCount; if(NULL != sp._pCount)//注意判断赋值对象是否为空 { ++(*_pCount); } } return *this; } T* operator->()//将原来的指针返回去,外边就可以用这个指针了 { return _p; } ~SharedPtr() { if (0 == --(*_pCount)) { delete _p; delete _pCount; _p = NULL; _pCount = NULL; } } T *_p; int *_pCount; };

循环引用情况代码

#include<iostream> #include<stdlib.h> #include"SharedPtr.h" using namespace std; template <typename T> struct Node { Node(const T& value) :_value(value) {} ~Node() {} SharedPtr<Node<T>> _ptr; SharedPtr<Node<T>> _next; T _value; }; void FunTest() { SharedPtr<Node<int>> p1(new Node<int>(10)); SharedPtr<Node<int>> p2(new Node<int>(20)); p1->_next = p2; p2->_ptr = p1; } int main() { FunTest(); system("pause"); return 0; }

我们来分析一下造成循环引用的原因,上述代码形成的结果如下 p1 的后继指向p2,p2的前驱指向p1,p1等p2释放,p2等p1释放,这样就会造成最后p1 ,p2都没有释放,造成内存泄露。 boost库里引入了weak_ptr来解决了循环引用的问题。

转载请注明原文地址: https://www.6miu.com/read-63085.html

最新回复(0)