boost源码剖析3----内存管理shared_ptr
来源:互联网 发布:黄子华 知乎 编辑:程序博客网 时间:2024/05/24 05:03
Shared_ptr类末班可以指向动态内存分配的对象,支持比较操作,可以搭配STL关联式容器,可以说是最智能的一种指针了,它与scoped_ptr一样是包装了new分配的动态对象,与scoped_ptr不同的是Shared_ptr引入了计数型的智能指针,可以被自由的赋值和拷贝,当引用为0时,才删除引用指向的对象。它的行为最接近原始指针,因此比auto_ptr和scoped_ptr使用范围更广。
shared的本身代码比较复杂,我把它经过一番休整,提取里面的关键部分,摘要如下:
template<class T> class shared_ptr{private: typedef shared_ptr<T> this_type;public: typedef T element_type; typedef T value_type; typedef T * pointer; typedef typename boost::detail::shared_ptr_traits<T>::reference reference;//特性萃取 shared_ptr(): px(0), pn()// never throws in 1.30+ 默认构造函数,指针为空,引用计数为0 { }explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete explicit表示只能显示构造对象,带 {//构造一个拥有指针 p 的 shared_ptr boost::detail::sp_enable_shared_from_this( this, p, p ); }template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)//构造一个拥有指针 p 和删除器 d 的 shared_ptr。//下面那个构造函数用 a 的一个拷贝分配内存 { boost::detail::sp_enable_shared_from_this( this, p, p ); }template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) { boost::detail::sp_enable_shared_from_this( this, p, p ); }shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws {//如果 r 为 empty,构造一个 empty shared_ptr,否则,//构造一个带有 r 的 shares ownership(共享所有权)的 shared_ptr } template<class Y> explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw {//构造一个带有 r 的 shares ownership(共享所有权)的 shared_ptr,并存储 r 中所存储指针的一个拷贝// it is now safe to copy r.px, as pn(r.pn) did not throw px = r.px; }template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn() {//构造一个 shared_ptr,就像存储了一个 r.release() 的返回值的拷贝 Y * tmp = r.get(); //auto_ptr失去指针的管理权 pn = boost::detail::shared_count(r); boost::detail::sp_enable_shared_from_this( this, tmp, tmp ); }void set();template<class Y> void reset(Y *p);bool unique() const; //判断是否为指针的唯一所有者long use_count() const;//当前指针引用计数private: template<class Y> friend class shared_ptr; template<class Y> friend class weak_ptr;#endif T * px; // contained pointer boost::detail::shared_count pn; // reference counter}; // shared_ptr用法1:
#include <boost\smart_ptr.hpp>#include <string>using namespace std;using namespace boost;int main(){boost::shared_ptr<int> a(new int(10));assert(a.unique());boost::shared_ptr<int> b = a;cout<<b.use_count()<<endl;//2//a[3] = 15;*a = 4;cout<<*a<<endl;//4b.reset();cout<<a.use_count()<<endl;//1return 0;}用法2:工厂函数
智能指针的作用在于消除new和delete的显示调用,但是在上面的例子里为了构造一个堆内存还是调用了new,前面说过,显示的调用delete或new可能会引发一系列问题,那么怎么消除new和delete的显示调用呢,那就要使用到工厂函数make_shared。它的名字模仿了STL中的make_pair,声明如下:template<class T, class ... args> shared_ptr<T>make_ shared(Args ... args);最多可以接受10个参数,它创建一个shared_ptr的对象并返回。下面例子说明它的用法:
#include <boost\smart_ptr.hpp>#include <string>#include <vector>using namespace std;using namespace boost;int main(){boost::shared_ptr<int> pt2 = boost::make_shared<int>(int(10));boost::shared_ptr<vector<string> > str = boost::make_shared<vector<string> >(10,"test");return 0;}用法3:桥接模式
桥接模式是一种结构设计模式,它把类的具体实现 细节对用户隐藏起来,达到类之间最小的耦合关系。例子如下:
#include <boost\smart_ptr.hpp>#include <string>using namespace std;using namespace boost;class test{private:class hide;boost::shared_ptr<hide> p1;public:test():p1(new hide){}void print(){p1->print();}};class test::hide{public:hide::hide(){}void print(){cout<<"hide print"<<endl;}};int main(){test a;a.print();}用法4:应用与标准容器
int main(){typedef vector<boost::shared_ptr<int> > vs;vs v(10);int i =0;for(vs::iterator pos = v.begin(); pos!=v.end();pos++){(*pos) = boost::make_shared<int>(++i);cout<<**pos<<endl;}boost::shared_ptr<int> p =v[9];*p =88;cout<<*v[9]<<endl;return 0;}注意vector存储的是shared_ptr,在对itertor解引用时得到shared_ptr,在解引用得到值。
用法5:定制删除器
假设有一个类socket,
class socket{private:int *p;public:socket(){}void close(){delete p;//其它操作}}
有一个对象socket s,那我们可以这样调用shared_ptr<socket> p(s,close),当离开作用域时,它会自动调用close释放资源。
- boost源码剖析3----内存管理shared_ptr
- boost::shared_ptr内存管理
- boost源码剖析1----内存管理scoped_ptr
- boost源码剖析2----内存管理scoped_array
- boost shared_ptr 源码解析
- boost shared_ptr 及C++内存管理的一些总结
- boost库的shared_ptr剖析
- C++ shared_ptr源码剖析
- Linux内存管理源码剖析
- Boost源码学习---shared_ptr.hpp
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- 同余定理
- jquery实现下拉动态菜单
- 使用jvisualvm监控JAVA程序,注意对程序性能的影响
- Pycharm的远程代码编辑
- hdu3487 Play with Chain(splay)
- boost源码剖析3----内存管理shared_ptr
- ccsprite注意事项
- Google Maps地图投影全解析(1):Web墨卡托投影
- 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket
- Hibernate4 执行SQL语句
- 个人收集关于vb的一些知识,希望以后可以温故知新咯!
- 基于jQuery的横向连续滚动【原创】
- android学习之点击事件的四种写法
- 跟踪G-Sensor有时不起作用的问题