Smart_ptr

来源:互联网 发布:php死循环设置不超时 编辑:程序博客网 时间:2024/05/29 08:45

RAII机制

C++程序员采用RAII机制(资源获取即初始化),在使用资源的类的构造函数中申请资源,

然后使用,最后在析构函数中释放资源.

scoped_ptr

用于确保能够正确地删除动态分配的对象;

拷贝构造函数+赋值操作符为私有的(禁止复制操作);

get();返回scoped_ptr内部保存的原始指针

auto_ptr的区别:

区别主要在于对拥有权的处理:

(1)scoped_ptr它不能转让所有权,永远不能被复制或被赋值!【拷贝构造函数+赋值操作符为私有的(禁止复制操作)】

    而auto_ptr可以。

scoped_ptr拥有它所指向的资源的所有权,并永远不会放弃这个所有权

(2)包含scoped_ptr的类必须定制自己的复制构造函数和赋值函数

用法:类似裸指针

scoped_ptr<std::string>p(new string("zpp"));
if(p)
cout<<*p<<endl;

scoped_ptr 和 Pimpl 用法

     

要求:必须记住要手工定义析构函数;原因是在编译器生成隐式析构函数时,类

impl还是不完整的,所以它的析构函数不能被调用。   

好的做法:使用引用型智能指针shared_ptr<impl>

优势:不需要手工去定义复制构造函数和赋值操作符,

而且可以定义空的析构函数,shared_ptr被设计为可以正确地用于未完成的类。

scoped_array

与scoped_ptr区别

scoped_array为数组做了scoped_ptr为单个对象的指针所做的事情:它负责释放内存。

区别

(1)只在于scoped_array是用delete[]操作符来做这件事的。

(2)它提供了operator[]来模仿一个裸数组。

shared_ptr

1,  在需要访问共享资源的对象之间共享资源的所有权, 

       注:shared_ptr对象间的拷贝,赋值会增加引用计数

2,  可以把对象指针存入标准库的容器中而不会有泄漏的风险,特别是在面对异常或要从容器中删除元素的时候。

3, 定制删除器,

  通过使用定制删除器,几乎所有资源类型都可以存入shared_ptr

4.从一个裸指针、另一个shared_ptr、一个std::auto_ptr、或者一个boost::weak_ptr构造。

   构造后引用计数设为1析构函数:引用计数--,0时,保存的指针被删除

5, 放入标准容器

   方式1:将容器作为shared_ptr的管理对象,shared_ptr<list<T>>

   方式2:shared_ptr作为容器的元素,vector<shared_ptr<T>>

6.多态容器需要在容器中存放多态的对象而且你不想切割它们,你必须用指针。如果你用裸指针,维护元素的完整性会非常复杂。

注:需要在容器中存放多态的对象:还可以使用指针容器【存储多态对象的指针】例如:typedefstd::vector<boost::shared_ptr<A> > container_type;

       typedef container_type::iterator iterator;

7.实现桥接模式:把类的具体实现细节对用户隐藏,达到类间的最小耦合关系

sample类,仅向外界暴露最小的细节,真正的实现在内部类impl,

class sample

{

private:

class impl;

shared_ptr<impl>p;

public:

sample();

void print();//外部接口

};

class sample::impl

{

public:

void print()

{cout<<"implprint";}

};

sample::sample():p(newimpl){}

voidsample::print(){ p->print();}

桥接模式的使用:

sample s;

s->print();

shared_array

用于共享数组所有权的智能指针;

与shared_ptr的不同之处

1】它是用于数组的而不是用于单个对象

2】增加了一个下标操作符,

3】不支持定制删除器

shared_arrayvector更有价值,因为它提供了对数组所有权的共享

weak_ptr

1】  weak_ptr是shared_ptr的观察员。它不会干扰shared_ptr所共享的所有权。

weak_ptr不会影响引用计数,例如从一个shared_ptr创建weak_ptr,shared_ptr的引用计数不会改变,

2】  当一个被weak_ptr所观察的shared_ptr要释放它的资源时,它会把相关的weak_ptr的指针设为空。--------------防止了weak_ptr持有悬空的指针。

3】  lock()返回一个引向weak_ptr所观察的资源的shared_ptr,增加引用计数

expired():若观察的资源已被删除,返回true


从weak_ptr获得shared_ptr的方法:

这两种方法都会使引用计数增加

1】传送weak_ptr给shared_ptr的构造函数,

2】通过调用weak_ptr::lock来获得一个shared_ptr

intrusive_ptr  很少使用了

1】  shared_ptr的插入式版本

2】典型的情况是对于那些已经写好了内部引用计数器的代码,而我们又没有时间去重写它(或者已经不能获得那些代码了)

3】另一种情况是要求智能指针的大小必须与裸指针大小严格相等,或者shared_ptr的引用计数器分配严重影响了程序的性能(我可以肯定这是非常罕见的情况!)。

4】它要求你来提供它所要的引用计数器

5】当intrusive_ptr递增或递减一个非空指针上的引用计数时,它是通过分别调用函数intrusive_ptr_add_ref和intrusive_ptr_release来完成的。

你必须为你的类重载这两个函数





0 0