share_ptr 的 知识梳理
来源:互联网 发布:全身美白 知乎 编辑:程序博客网 时间:2024/05/16 16:00
share_ptr 的 知识梳理笔记
最近学习share_ptr 的时候发现这是个很有用的智能指针,无论是内存管理还是线程安全,以及自定义删除器, 所以觉得还是记录分享一下,同时也巩固一下自己的学习成果
1,share_ptr 是何物
采用引用计数的智能指针。 shared_ptr基于“引用计数”模型实现,多个shared_ptr可指向同一个动态对象,并维护了一个共享的引用计数器,记录了引用同一对象的shared_ptr实例的数量。当最后一个指向动态对象的shared_ptr销毁时,会自动销毁其所指对象(通过delete操作符)。shared_ptr的默认能力是管理动态内存,但支持自定义的Deleter以实现个性化的资源释放动作。头文件:。
基本操作:shared_ptr的创建、拷贝、绑定对象的变更(reset)、shared_ptr的销毁(手动赋值为nullptr或离开作用域)、指定deleter等操作。
shared_ptr的创建,有两种方式,一,使用函数make_shared(会根据传递的参数调用动态对象的构造函数);二,使用构造函数(可从原生指针、unique_ptr、另一个shared_ptr创建)
shared_ptr<int> p1 = make_shared<int>(1);// 通过make_shared函数 shared_ptr<int> p2(new int(2));// 通过原生指针构造
此外智能指针若为“空“,即不指向任何对象,则为false,否则为true,可作为条件判断。可以通过两种方式指定deleter,一是构造shared_ptr时,二是使用reset方法时。可以重载的operator->, operator *,以及其他辅助操作如unique()、use_count(), get()等成员方法。
2,shared_ptr的线程安全性
boost官方文档对shared_ptr线程安全性的正式表述是:shared_ptr对象提供与内置类型相同级别的线程安全性。【shared_ptrobjects offer the same level of thread safety as built-in types.】具体是以下三点。
同一个shared_ptr对象可以被多线程同时读取。【A shared_ptrinstance can be “read” (accessed using only const operations)simultaneously by multiple threads.】
不同的shared_ptr对象可以被多线程同时修改(即使这些shared_ptr对象管理着同一个对象的指针)。【Different shared_ptr instances can be “written to”(accessed using mutable operations such as operator= or reset) simultaneouslyby multiple threads (even when these instances are copies, and share the samereference count underneath.) 】
任何其他并发访问的结果都是无定义的。【Any other simultaneous accesses result in undefined behavior.】同一个shared_ptr对象不能被多线程直接修改,但可以通过原子函数完成。
我简单地理解为,除了多线程直接修改(非原子函数)同一个share_ptr ,其他都是安全的
3,share_ptr 使用中可能碰到的有意思问题,循环引用
“循环引用”简单来说就是:两个对象互相使用一个shared_ptr成员变量指向对方的会造成循环引用。导致引用计数失效。而解决的办法其实是另一个weak_ptr 智能指针的使用,这里具体就不多说了,需要知道的是,weak_ptr不参与引用计数, 两个常用的功能函数:expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用指针, 譬如
void doSomthing() { shared_ptr<B> pp = pb.lock(); if(pp)//通过lock()方法来判断它所管理的资源是否被释放 { cout<<"sb use count:"<<pp.use_count()<<endl; } }
4,share_ptr 的自定义删除器
这个直接上代码吧,两个代码片段,看了应该就明白了,不明白的你再多看两遍,呵呵~~
#include <iostream>#include <memory>struct dialog_t { };template<class T>struct deleter_t{ void operator () (T* x) const { if(x != NULL ) { std::cout << __LINE__ << std::endl; delete x; x=NULL; } }};int main (){ auto const p = std::shared_ptr<dialog_t>(new dialog_t, deleter_t<dialog_t>{});}
分割开,上面这个就是个单独的代码片,下面的是有测试用例的
template<class T>//注意这里有模版 struct Del { void operator()(const T* ptr) { delete ptr; } }; struct Free//注意这里没有模版 { void operator()(void* ptr) { free(ptr); } }; struct Fclose { void operator()(FILE* ptr) { fclose(ptr); } }; template<class T,class Deleter=Del<T>> class SharedPtr { public: SharedPtr(T* ptr, Deleter del) :_ptr(ptr) , _pCount(new long(1)) , _del(del) {} SharedPtr(T* ptr) :_ptr(ptr) , _pCount(new long(1)) {} ~SharedPtr() { _Release(); } protected: void _Release() { if (--*_pCount == 0) { _del(_ptr); delete _pCount; } } private: T* _ptr; long* _pCount; Deleter _del; };
测试用例
void Test() { SharedPtr<int>sp1(new int(1)); SharedPtr<int,Free>sp2((int*)malloc(sizeof(int) * 10), Free());//注意怎么调用的 }
先到这里,后面还有的话再补上,当然可爱的你也可以在评论里直接追加,3q~
- share_ptr 的 知识梳理
- 知识系统的梳理
- boost::share_ptr的缺陷
- share_ptr的一点片段
- share_ptr的问题
- share_ptr的正确使用方法
- 自己写的share_ptr
- Laravel的migration知识梳理
- jQuery的.each()知识梳理
- share_ptr
- share_ptr
- Share_ptr
- 知识梳理
- 知识梳理
- 知识梳理
- 知识梳理
- 知识梳理
- share_ptr 引用计数的实现
- FragmentTabHost嵌套ViewPager,Fragment第二次点击不显示的问题
- JS实现隔行变色
- 数据库权限
- 谷歌深度学习公开课学习笔记(1)
- 如何在无显示器的Ubuntu下跑前端测试
- share_ptr 的 知识梳理
- 使用Session防止表单重复提交
- 剑指Offer前十题
- 实现右滑关闭Activity的简单方法
- jquery中的ajax处理跨域问题-之-----jsonp
- 高并发Java 七 并发设计模式
- 在Eclipse中使用JUnit4进行单元测试(初级篇)
- Caused by: org.apache.ibatis.type.TypeException: Could not resolve type alias 'BaseResultMap'
- Hadoop伪分布式环境搭建