Boost库之shared_ptr应用

概解:
本文是自己在学习boost库完全开发的时候顺手做的笔记,摘出其中自认为是比较重要的部分以作整理并写成博文,分享出来,很是奇怪csdn代码块那块有颜色代码,不知道怎么去掉、、、因为没咋仔细研究、、、所以这编将就先弄着,等有时间再仔细研究一番这个:
      shared_ptr非常有价值、非常重要、非常有用!
      shared_ptr是一个最像指针的"智能指针",是boost::smart_ptr库中最有价值、最重要的组成部分,也是最有用的,Boost库中许多组件--甚至还包括其他一些领域的智能指针都使用了shared_ptr。

     shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针,可以被自由地拷贝和赋值,在任意的地方共享它。当没有代码使用(引用计数为0)它才删除呗包装的动态分配的对象,shared_ptr也可以被安全的放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷;

类摘要:

template<class T>
class shared_ptr
{
     public:
          typdef T elment_type;
          
          shared_ptr();
          template<class Y> explicit shared_ptr(Y *p);
          template<class Y,class D> shared_ptr(Y *p,D d);
          ~shared_ptr();

          shared_ptr(shared_ptr const &r);
          template<class Y>explicit shared_ptr(std::auto_ptr<Y> &r);
          
          shared_ptr& operator=(shared_ptr const &r);
          template<class Y>shared_ptr &operator=(shared_ptr<Y> const &r);
          template<class Y>shared_ptr &operator=(std::auto_ptr<Y> &r); 

          void reset();
          template<class Y>void reset(Y *p);
          template<class Y,class D>void reset(Y *p,D d);

          T &operator*() const;
          T *operator->() const;
          T *get() const;

          bool unique() const;
          long use_count() const;

          operator unspecified-bool-type() const;
          void swap(shared_ptr &b);
};
shared_ptr的定义:

shared_ptr<int> psi(new int);
assert(spi);
*spi = 235;

shared_ptr<string> sps(new string("smart"));
assert(sps->size() == 5);

shared_ptr有多种形式的构造 函数,应用于各种可能的情形:
     a、无参的shared_ptr() 创建一个持有空指针的shared_ptr;
     b、shared_ptr(Y *p)获得指向类型T的指针p的管理权,同时引用计数置为1,这个构造函数要求Y类型必须能够转换为T类型;
     c、shared_ptr(shared_ptr const &r)从另外一个shared_ptr获得指针的管理权,同时引用计数加1,结果是两个shared_ptr共享一个指针的管理权;
     d、shared_ptr(std::auto_ptr<Y> &r)从一个auto_ptr获得指针的管理权,引用计数置为1,同时auto_ptr自动失去管理权;
     e、operator=赋值操作符可以从另外一个shared_ptr或auto_ptr获得指针的管理权,其行为同构造函数;
     f、shared_ptr(Y *p,D d)行为类似shared_ptr(Y *p),但使用参数d指定了析构时的定制删除器,而不是简单的delete。

特点:
      a、sharedn_ptr的reset()函数行为与scoped_ptr也不尽相同,它的作用是将引用计数减1,停止对指针共享,除非引用计数为0,否则不会发生删除操作,带参的reset()类似同形式的构造函数,原指针引用计数减1的同时改为管理另一个指针;
     b、shared_ptr有两个专门的函数来检查引用计数,unique()在shared_ptr是指针的唯一所有者时返回true(这时shared_ptr的行为类似于auto_ptr或者socped_ptr),use_count()返回当前只针对额引用计数,注意!use_count()应该仅仅用于测试或者调试环境,它不提供高效率的操作,而且有时候可能是不可用的(极少数情形),而unique()则是可靠的,任何时候都可以用,而且use_count() == 1速度更快;
     c、shared_ptr还支持比较运算,可以测试两个shared_ptr的相等或者不想等,比较基于内部保存的指针,相当于a.get() == b.get().shared_ptr还可以使用operatoe<比较大小,同样基于内部保存的指针,但不提供除operator<以外的比较操作符,这使得shared_ptr可以被用于标准关联容器(set And map):
typedef shared_ptr<string> sp_t;         //shared_ptr类型定义
map<sp_t,int> m;                         //标准映射容器
sp_t sp(new string(:"one"));             //一个shared_ptr对象
m[sp] = 111;                             //关联数组用法

类型的转换:
      shared_ptr的类型转换主要体现在类的多态。如将一个基类以及子类的指针进行互转,shared_ptr不能直接使用标准库中提供的类型转换函数,诸如:static_cast<T *>(p.get())这种用法,这将导致指针管理处于不可控状态,但是shared_ptr有一套自己的类型转换接口:
a、static_pointer_cast<T>()
b、const_pointer_cast<T>()
c、dynamic_pointer_cast<T>()
上面三个接口与标准库提供的类型转换类似,但返回的是转型后的shared_ptr;如下示例,将一个指针进行类型转换后再转换回去的操作:
shared_ptr<std::exception> sp1(new bad_exception("error"));
shared_ptr<bad_exception> sp2 = dynamic_pointer_cast<bad_exception>(sp1);          //向下转型
shared_ptr<std::exception> sp3 = static_pointer_cast<std::exception>(sp2);         //向上转型
assert(sp3 == sp1);
 此外,shared_ptr还支持流输出操作符operator<<,输出内部的指针值,方便调试;

shared_ptr的使用:
      shared_ptr100%涵盖了new的基本功能,且使用完毕后不用想new操作符那样进行手动delete,而且shared_ptr也是线程安全的,可以同时在多个线程内进行读取操作,其它访问均为未定义的操作,示例如下:
样例一:
shared_ptr<int> sp(new int(10));         //指向int的shared_ptr
assert(sp.unique());                     //shared_ptr是指针的唯一持有者

shared_ptr<int> sp2 = sp;                //第二个指针,拷贝构造且计数加1
assert(sp == sp2 && sp.use_count() == 2);//两个相等,指向同一个对象,引用计数为2

*sp2 = 100;                              //使用解引用操作符修改被指对象
assert(*sp == 100);                      //另一个对象shared_ptr的值也同时被修改

sp.reset();                              //停止shared_ptr的使用
assert(!sp);                             //sp不再持有任何指针,此时为null

样例二:
class shared                               
{
     private:
           shared_ptr<int> p;               
     public:
          shared(shared_ptr<int> p_):p(p_){}
          void print()                      
          {
               cout << "count: " << p.use_count() << "V = " << *p << endl;
          }
};

void print_func(shared_ptr<int> p)         
{
     cout << "count: " << p.use_count() << "value: " << *p << endl;
}

int main()
{
     shared_ptr<int> p(new int(100));
     shared s1(p), s2(p);

     s1.print();
     s2.print();

     *p = 20;
     print_func(p);

     s1.print();
}

上例详解:
      样例二定义了一个类以及一个函数,需要注意的是,两者都是直接拷贝的方式传递的参数,而不是引用,这样的话在创建shared_ptr以及实例化shared类的时候count此时的计数为3,之后又再次往print_func传递了参数此时count值为4,因为shared_ptr在退出的时候会自动调用析构所以在最后那块的打印count为3;





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值