shared_ptr循环引用&定置删除器-创新互联
shared_ptr虽然方便,但是它有着一个致命的缺陷就是循环引用问题,因为shared_ptr本身并没有能力解决这个问题,所以我们又引入了弱指针weak_ptr来辅助shared_ptr解决这个问题。
公司主营业务:成都做网站、网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联推出耒阳免费做网站回馈大家。那么循环引用又是什么场景?
举个栗子:
假设现在我们要创建一个双向×××链表,但是这个链表的指针域全部都用shared_ptr维护:
struct Node
{
int _data;
shared_ptr
shared_ptr
}
假设现在先创建两个结点,并用shared_ptr维护这两个结点:
shared_ptr
shared_ptr
现在将这两个指针互相连接:
sp1->_next=sp2;
sp2->prev=sp1;
为了解决循化引用问题,我们又引入了weak_ptr弱指针,用来辅助shared_ptr。注意weak_ptr不能单独使用,必须辅助shared_ptr才能使用。weak_ptr是一种不控制所指向对象生存周期的智能指针,它指向一个由shared_ptr管理的对象,将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一但最后一个指向对象的shared_ptr被销毁,对象就会被销毁,即使有weak_ptr指向对象,对象还是会被释放。
例:
所以为了解决上面栗子中的循环引用问题,我们可以将指针域的智能指针声明为弱指针。
struct Node
{
int _data;
weak_ptr
weak_ptr
}
二、定置删除器
一般情况下,我们都用智能指针是用来管理动态内存的,其实智能指针是用来管理资源的,资源很多,动态内存只是资源的一种,比如说我们可以用智能指针来管理文件,那么我们就不能用智能指针默认的删除器了,因为要管理文件的话最后是fclose,而不是delete,所以我们就必须自己定制一个删除器。
例:以管理文件为例,实现定置删除器。
要实现定置删除器,就要用到仿函数:仿函数就是将"()"重载。
//定置删除器的仿函数 struct Fclose { void operator()(void *ptr) { fclose((FILE *)ptr); cout << "fclose()" << endl; } }; void test() { boost::shared_ptrsp(fopen("test.txt","w"),Fclose()); //调用构造函数构造一个匿名对象传递过去,文件正常关闭 } 再举一个栗子: 用智能指针管理malloc开辟的动态内存,那么我们在释放的时候就要用free释放: //定置删除器的仿函数 struct Free { void operator()(void *ptr) { free(ptr); } }; void test() { boost::shared_ptr sp((int *)malloc(sizeof(int)),Free()); //能够正确的释放空间 }
三、简单的实现一个有定置删除器的shared_ptr
struct Fclose { void operator()(void *ptr) { fclose((FILE *)ptr); cout << "fclose()" << endl; } }; struct Free { void operator()(void *ptr) { free(ptr); cout << "free()" <class SharedPtr //采用引用计数,实现一个可以有多个指针指向同一块内存的类模板,SharedPtr是类模板,不是智能指针类型 { public: SharedPtr(T* ptr, D del = DefaultDel()); SharedPtr(const SharedPtr & sp); SharedPtr & operator=(SharedPtr sp); T& operator*(); T* operator->(); ~SharedPtr(); int Count() { return *_pCount; } private: void Release() { if (--(*_pCount) == 0) { _del(_ptr); delete _pCount; _ptr = NULL; _pCount = NULL; } } private: T* _ptr; int* _pCount; D _del; }; template SharedPtr ::SharedPtr(T* ptr,D del) :_ptr(ptr) , _pCount(new int(1)) ,_del(del){} template SharedPtr ::SharedPtr(const SharedPtr & sp) { _ptr = sp._ptr; _pCount= sp._pCount; ++(*_pCount); } template SharedPtr & SharedPtr ::operator=(SharedPtr sp) { std::swap(sp._ptr,_ptr); std::swap(sp._pCount,_pCount); return *this; } template T& SharedPtr ::operator*() { return *_ptr; } template T* SharedPtr ::operator->() { return _ptr; } template SharedPtr ::~SharedPtr() { Release(); } //测试用例 void test() { SharedPtr sp(new int(1)); SharedPtr sp1(fopen("test.txt","w"),Fclose()); SharedPtr sp3((string *)malloc(sizeof(string)),Free()); } int main() { test(); system("pause"); return 0; }
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
网页题目:shared_ptr循环引用&定置删除器-创新互联
文章分享:http://scyanting.com/article/diiegs.html