c++11 auto_ptr介绍
在代码里面看到了auto_ptr这个东西,正好以前一哥们曾经问过我这个问题..所以特意去搜了搜帖子,学习学习
http://www.cnblogs.com/gaoxianzhi/p/4451803.html
头文件 : #include <memory>
使用 : std::auto_ptr
作用 : 动态分配对象以及当对象不再需要时自动执行清理(意思就是你不用再去关心什么时候delete了也不用担心发生异常会有内存泄漏)
实现 : 在C++中, auto_ptr是一个类,它用来实现对动态分配对象的自动释放。
智能指针代码分析:
1 template<class T> //模板类 2 class auto_ptr 3 { 4 private: 5 T*ap; //int* ap; char* ap; father* ap; child* ap; 6 public: 7 //constructor & destructor-----------------------------------(1) 8 explicit auto_ptr(T*ptr=0)throw():ap(ptr)//explicit->防止隐式转换(隐式转换只会在构造函数只有一个参数的时候发生) 9 { 10 } 11 12 ~auto_ptr()throw() //直接删除ap.如果ap是null也没关系,c++不会认为错误 13 { 14 delete ap; 15 } 16 //Copy & assignment--------------------------------------------(2) 17 auto_ptr(auto_ptr& rhs)throw():ap(rhs.release()) //拷贝构造函数 18 { 19 } 20 21 template<class Y> //模板拷贝构造函数-->重载的拷贝构造函数 22 auto_ptr(auto_ptr<Y>&rhs)throw():ap(rhs.release()) 23 { 24 } 25 26 auto_ptr& operator=(auto_ptr&rhs)throw() //重载的赋值操作符 27 { 28 reset(rhs.release()); 29 return*this; 30 } 31 32 template<class Y> //模板重载的赋值操作费 33 auto_ptr& operator=(auto_ptr<Y>&rhs)throw() 34 { 35 reset(rhs.release()); 36 return*this; 37 } 38 39 //Dereference----------------------------------------------------(3) 40 T& operator*()const throw() //重载* 注意返回的是类的引用 41 { 42 return *ap; 43 } 44 T* operator->()const throw() //重载-> 45 { 46 return ap; 47 } 48 49 //Helper functions------------------------------------------------(4) 50 //value access 51 T* get()const throw() 52 { 53 return ap; 54 } 55 56 //release owner ship 57 T* release()throw() //此函数是在 返回临时对象??????????? 58 { 59 T*tmp(ap); //调用构造函数tmp.ap 执行this->ap 60 ap=0; 61 return tmp; 62 } 63 64 //reset value 65 void reset(T*ptr=0)throw() 66 { 67 if(ap!=ptr) 68 { 69 delete ap; 70 ap=ptr; 71 } 72 } 73 74 //Special conversions-----------------------------------------------(5) //后面的真心看不懂啊 75 template<class Y> 76 struct auto_ptr_ref 77 { 78 Y* yp; 79 auto_ptr_ref(Y* rhs) : yp(rhs){} 80 }; 81 auto_ptr(auto_ptr_ref<T>rhs)throw():ap(rhs.yp) //辅助的拷贝构造函数 82 { 83 } 84 85 auto_ptr& operator=(auto_ptr_ref<T>rhs)throw() 86 { 87 reset(rhs.yp); 88 return*this; 89 } 90 91 template<class Y> 92 operator auto_ptr_ref<Y>()throw() 93 { 94 return auto_ptr_ref<Y>(release()); 95 } 96 97 template<class Y> 98 operator auto_ptr<Y>()throw() 99 { 100 return auto_ptr<Y>(release()); 101 } 102 };
1
2
|
int *p= new int (0); auto_ptr< int > ap(p); |
注意事项:
1).auto_ptr析构的时候肯定会删除他所拥有的那个对象,所以我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。
1 int* p = new int(0); 2 auto_ptr<int> ap1(p); 3 auto_ptr<int> ap2(p); //错误,一个p给了两个智能指针
2).auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针
1 int* pa = new int[10]; 2 auto_ptr<int> ap(pa); //错误,在delete的时候只会删除数组的第一个元素,其他元素申请的空间不会被删除
3). 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型
4.)因为C++保证删除一个空指针是安全的, 所以我们没有必要把析构函数写成:
1
2
3
4
|
~auto_ptr() throw () { if (ap) delete ap; } |
2 拷贝构造与赋值
与引用计数型智能指针不同的,auto_ptr要求其对“裸”指针的完全占有性。也就是说一个“裸”指针不能同时被两个以上的auto_ptr所拥有。那么,在拷贝构造或赋值操作时,我们必须作特殊的处理来保证这个特性。auto_ptr的做法是“所有权转移”,即拷贝或赋值的源对象将失去对“裸”指针的所有权,所以,与一般拷贝构造函数,赋值函数不同, auto_ptr的拷贝构造函数,赋值函数的参数为引用而不是常引用(const reference).当然,一个auto_ptr也不能同时拥有两个以上的“裸”指针,所以,拷贝或赋值的目标对象将先释放其原来所拥有的对象。
1
2
3
4
|
int *p= new int (0); auto_ptr< int >ap1(p); auto_ptr< int >ap2=ap1; cout<<*ap1; //错误,此时ap1只剩一个null指针在手了 |
1
2
3
4
5
6
7
8
|
void f(auto_ptr< int >ap) { cout<<*ap; } auto_ptr< int >ap1( new int (0)); f(ap1); cout<<*ap1; //错误,经过f(ap1)函数调用,ap1已经不再拥有任何对象了。 |
1
2
|
class base{}; class derived: public base{}; |
1
|
auto_ptr<base>apbase=auto_ptr<derived>( new derived); |
1
2
3
4
5
6
|
A a1; A a2(a1); A a3; a3=a1; //那么 a2==a1,a3==a1 |
1
2
3
4
5
6
7
8
|
struct A { void f(); } auto_ptr<A>apa( new A); (*apa).f(); apa->f(); |
1
|
auto_ptr< int >ap1=auto_ptr< int >( new int (0)); |