C++程序员采用RAII机制(资源获取即初始化),在使用资源的类的构造函数中申请资源,
然后使用,最后在析构函数中释放资源.
用于确保能够正确地删除动态分配的对象;
拷贝构造函数+赋值操作符为私有的(禁止复制操作);
get();返回scoped_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_array为数组做了scoped_ptr为单个对象的指针所做的事情:它负责释放内存。
区别
(1)只在于scoped_array是用delete[]操作符来做这件事的。
(2)它提供了operator[]来模仿一个裸数组。
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();
用于共享数组所有权的智能指针;
1】它是用于数组的而不是用于单个对象
2】增加了一个下标操作符,
3】不支持定制删除器
但shared_array比vector更有价值,因为它提供了对数组所有权的共享
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
这两种方法都会使引用计数增加
1】传送weak_ptr给shared_ptr的构造函数,
2】通过调用weak_ptr::lock来获得一个shared_ptr
1】 shared_ptr的插入式版本
2】典型的情况是对于那些已经写好了内部引用计数器的代码,而我们又没有时间去重写它(或者已经不能获得那些代码了)
3】另一种情况是要求智能指针的大小必须与裸指针大小严格相等,或者shared_ptr的引用计数器分配严重影响了程序的性能(我可以肯定这是非常罕见的情况!)。
4】它要求你来提供它所要的引用计数器。
5】当intrusive_ptr递增或递减一个非空指针上的引用计数时,它是通过分别调用函数intrusive_ptr_add_ref和intrusive_ptr_release来完成的。
你必须为你的类重载这两个函数