C++ 智能指针 boost::scoped_ptr分析

1.scoped_ptr的实现原理及特性安全

特性:scoped_ptr和auto_ptr相似,但最大的区别就是不能转让管理权限,也就是说scoped_ptr禁止用户进行拷贝和赋值函数

实现原理:如何才能禁止一个类进行拷贝和复制呢?咱们只须要将类的拷贝构造函数和赋值运算符重载的访问限定符设置为私有的能够spa

样例以下:设计

class ScopedPtr{ private: ScopedPtr(const ScopedPtr& sp); ScopedPtr& operator(const ScopedPtr& sp); };

scoped_ptr和auto_ptr相似,它包装了new操做符在堆上分配的动态对象,可以保证动态建立的对象在任什么时候候均可以被正确的删除,可是scoped_ptr的全部权更加严格,不能转让,一旦scoped_ptr得到了对象的管理权,你就没法再从它那里去回来代理

正如scoped_ptr(局部指针)名字的含义同样:这个指针只能在做用域里使用,不但愿被转让指针

实现以下:code

template<class T>
class scoped_ptr { private: T *px; scoped_ptr(scoped_ptr const &); scoped_ptr & operator=(scoped_ptr const &); public: explicit scoped_ptr(T *p = 0); ~scoped_ptr(); void reset(T *p = 0); T & operator*()const; T * operator->()const; T * get()const; operator unspecified-bool-type()const; void swap(scoped_ptr & b); };

分析:对象

scoped_ptr的构造函数接受一个类型为T*的指针p,建立出一个scoped_ptr对象,并在内部保存指针参数p,p必须是一个new表达式动态分配的结果或是一个空指针,当scoped_ptr的对象生命周期结束时,析构函数会使用delete操做自动销毁所保存的指针对象,从而正确的回收资源。blog

scoped_ptr同时把拷贝构造函数和赋值操做都声明为私有,禁止对scoped_ptr的复制操做,保证了被它管理的指针不能被转让全部权生命周期

成员函数reset的功能是重置scoped_ptr,它删除原来保存的指针,再保存新的指针值p,若是p是空指针,那么scopted_ptr将不能持有任何指针,通常状况下reset不该该配调用,由于它违背了scopted_ptr的本意---资源应该一直由scoped-ptr本身自动管理

实际上拥有权不可转移不够方便,swap成员函数能够交换两个scopted_ptr保存的原始指针,须要知道的是,scoped1.swap(scoped2) 只能用于它的定义所在的智能指针,而swap(scoped1,scoped2) 能够更普遍的用于不少指针类型,包括裸指针和第三方智能指针

scoped_ptr用operator*()和operator->()重载了引用操做符和箭头操做符,以模仿被代理的原始指针的行为,所以能够把scoped_ptr对象如同指针同样使用,若是scoped_ptr保存空指针,那么这两个操做都是未定义的

scoped_ptr不支持比较操做,不能在两个scoped_ptr之间,scoped_ptr和原始指针之间,scoped_ptr和空指针之间,进行相等或者不相等的比较操做,咱们也没法为它编写额外的比较函数,由于其=和!=两个操做符都是私有的


2.scoped_ptr与auto_ptr的区别

1.scoped_ptr和auto_ptr的用法几乎同样,大多数状况下均可以与auto_ptr互换,它能够从一个auto_ptr得到指针的管理权(同时auto_ptr失去指针管理权)

2.scoped_ptr和auto_ptr同样不能用做容器的元素,可是缘由不一样,auto_ptr是由于它的转移语义,而scoped_ptr则是不支持拷贝和赋值,不符合容器对元素类型的要求

3.scoped_ptr和auto_ptr的根本区别在于全部权,auto_ptr被特地设计为全部权是能够被转移的,能够在函数之间传递,同一时刻只能有一个auto_ptr管理指针,而scoped_ptr把拷贝构造函数和赋值函数都声明为私有的,拒绝了指针全部权的转让,只有scoped_ptr本身可以管理指针,其余人都无权访问被管理的指针,从而保证了指针的绝对安全

4.若是代码企图从一个scoped_ptr构造或赋值另外一个scoped_ptr,那么编译器会报错,阻止你这么作,从而保护你的代码,scoped_ptr更明确的表达了原始代码编写者的意图:只能在定义的做用域内使用,不可转让,这在代码后续的维持生命周期中很重要

样例以下:

template<typename T>
class ScopedPtr { public: ScopedPtr(T* ptr=NULL):_ptr(ptr){} ~ScopedPtr(){ if(_ptr!=NULL) { delete _ptr; _ptr=NULL; } } private: ScopedPtr(const ScopedPtr &sp); ScopedPtr& operator=(const ScopedPtr &sp); private: T *_ptr; }; int main() { ScopedPtr<int> sp1(new int(10)); ScopedPtr<int> sp2(new int(20)); //ScopedPtr<int> sp3(sp1); //编译错误 拷贝函数私有 //sp1=sp2; //编译错误 =操做符私有
}


因为boost::scoped_ptr独享指针全部权,当咱们真的须要复制时,需求便知足不了,如此咱们再引入一个智能指针boost::shared_ptr专门处理复制,参数传递的状况,下一节咱们探讨boost::shared_ptr智能指针

相关文章
相关标签/搜索