Chinaunix首页 | 论坛 | 博客
  • 博客访问: 892060
  • 博文数量: 299
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2493
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-21 10:07
个人简介

Linux后台服务器编程。

文章分类

全部博文(299)

文章存档

2015年(2)

2014年(297)

分类: C/C++

2014-10-30 15:29:10

weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手,而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和operator->,它的最大作用在于协助shared_ptr,像旁观者那样观测资源的使用情况。

 

类摘要:

  1. template<class T> class weak_ptr{  
  2.      public:  
  3.      weak_ptr();  
  4.      template<class Y> weak_ptr(shared_ptr const & r);  
  5.      weak_ptr(weak_ptr const & r);  
  6.        
  7.      ~weak_ptr();  
  8.      weak_ptr & operator=(weak_ptr const &r);  
  9.        
  10.      long use_count() const;  
  11.      bool expired() const;  
  12.      shared_ptr lock() const;  
  13.        
  14.      void reset();  
  15.      void swap(weak_ptr &b);     
  16. };  


weak_ptr是一个“弱”指针,但它能够完成一些特殊的工作,足以证明它的存在价值。

weak_ptr被设计为与shared_ptr共同工作,可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。同样,在weak_ptr析构时也不会导致引用计数的减少,它只是一个静静地观察者。

使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count() == 0,但更快,表示观测的资源(也就是shared_ptr管理的资源)已经不复存在了。

weak_ptr 没有重载operator*和->,这是特意的,因为它不共享指针,不能操作资源,这是它弱的原因。但它可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象,从而操作资源。当expired() == true的时候,lock()函数将返回一个存储空指针的shared_ptr。

 

使用示例:

  1. int main(){  
  2.    shared_ptr<int> sp(new int(10));  
  3.    assert(sp.use_count() == 1);  
  4.    //create a weak_ptr from shared_ptr  
  5.    weak_ptr<int> wp(sp);  
  6.    //not increase the use count  
  7.    assert(sp.use_count() == 1);  
  8.    //judge wp is invalid  
  9.    //expired() is equivalent with use_count() == 0  
  10.    if(!wp.expired()){  
  11.       shared_ptr<int> sp2 = wp.lock();//get a shared_ptr  
  12.       *sp2 = 100;  
  13.       assert(wp.use_count() == 2);  
  14.       cout << *sp2 << endl;  
  15.    }//out of scope,sp2 destruct automatically,use_count()--;  
  16.    assert(wp.use_count() == 1);  
  17.    sp.reset();//shared_ptr is invalid  
  18.    assert(wp.expired());  
  19.    assert(!wp.lock());  
  20. }  


获得this的shared_ptr

weak_ptr的一个重要用途是获得this指针的shared_ptr,使对象自己能够生产shared_ptr管理自己:对象使用weak_ptr观测this指,这并不影响引用计数,在需要的时候就调用lock()函数,返回一个符合要求的shared_ptr使外界使用。

这个解决方案被实现为一个惯用法,在头文件定义了一个助手类enable_shared_from_this,其声明如下:

  1. template<class T>  
  2. class enable_shared_from_this  
  3. {  
  4. public:  
  5.    shared_ptr shared_from_this();  
  6. }  


使用的时候只需要让想被shared_ptr管理的类从它继承即可,成员函数shared_from_this()会返回this的shared_ptr

使用示例:

  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. using namespace boost;  
  6. using namespace std;  
  7. class self_shared:  
  8. public enable_shared_from_this{  
  9.     public:  
  10.     self_shared(int n):x(n){}  
  11.     int x;  
  12.     void print(){  
  13.     cout << "self_shared:" << x << endl;  
  14.     }  
  15. };  
  16. int main(){  
  17.     shared_ptr sp =   
  18.                            make_shared(315);  
  19.     sp->print();  
  20.     shared_ptr p = sp->shared_from_this();  
  21.     p->x = 100;  
  22.     p->print();    
  23.   
  24. }  


运行结果:

self_shared:315
self_shared:100

 

需要注意的是千万不能从一个普通对象(非shared_ptr)使用shared_from_this ()获取shared_ptr,如

self_shared ss;

shaerd_ptr p = ss.shared_from_this();//error

 

这样虽然语法上能通过,编译也无问题,但在运行时会导致shared_ptr析构时企图删除一个栈上分配的对象,发生未定义行为。

 

关于intrusive_ptr

intrusive_ptr是一个侵入式的引用计数型指针,它可以用于以下情形:

对内存占用的要求非常严格,要求必须与原始指针一样;

现存代码已经有了引用计数机制管理的对象。

boost库不推荐intrusive_ptr,因为shared_ptr已经非常强大且灵活,工作得足够好,可以满足绝大部分(99.99%)的需要。

如果有兴趣,可以自行翻阅boost文档。

阅读(1807) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~