关于智能指针auto_ptr
智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个
感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解。
本篇主要介绍auto_ptr
其特点如下:
1.首先auto_ptr智能指针是个封装好的类;
2.是采用栈上的指针去管理堆上的内容,所以auto_ptr所管理的对象必须是new出来的,也不能是malloc出来的,
原因:在auto_ptr的实现机制中,采用的是delete 掉一个指针,该delete一方面是调用了指针所指对象的析构函数(这也是为什么采用智能指针,new了一个对象,但是不用delete的原因),另一方面释放了堆空间的内存;
3.一块堆上的内存不能被两个智能指针同时指向(这个就是所有权和管理权的问题),想想也是,如果两个智能指针同时指向的话,每个智能指针对象析构的时候,都会调用一次delete,导致堆空间内存被释放两次,然而这是不被允许的。
4.aut0_ptr不能管理数组,因为析构调用的是delete,如果管理数组的话,需要调用delete[];
相比于普通指针的额优点就是:
普通指针在new 和delete之间发生异常,并且异常不能被捕获的话,就不会执行delete,那么这片内存就不能被回收。
但是auto_ptr就不会存在这样的问题。
其具体实现代码如下:应该是别人写的啊,感觉写的很不错啊,基本实现了auto_ptr的所有功能,而且容易读懂!
1 //auto_ptr.h 2 3 #ifndef AUTO_PTR_H 4 #define AUTO_PTR_H 5 6 template<typename T> 7 class auto_ptr 8 { 9 public : 10 //使用explicit关键字避免隐式转换 11 explicit auto_ptr(T* p=0); 12 13 ~auto_ptr(); 14 15 //使用另一个类型兼容的auto_ptr来初始化一个新的auto_ptr 16 template<typename U> 17 auto_ptr(auto_ptr<U>& rhs); 18 19 template<typename U> 20 auto_ptr<T>& operator=(auto_ptr<U>& rhs); 21 22 T& operator*() const; 23 T* operator->() const; 24 25 //返回原始对象的指针 26 T* get() const; 27 //放弃指针的所有权 28 T* release(); 29 //删除原有指针并获得指针的p的所有权 30 void reset(T* p=0); 31 32 private: 33 T* pointee; 34 35 }; 36 37 template<typename T> 38 auto_ptr<T>::auto_ptr(T* p) 39 :pointee(p) 40 {} 41 42 template<typename T> 43 template<typename U> 44 auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs) 45 :pointee(rhs.release()) 46 {} 47 48 template<typename T> 49 auto_ptr<T>::~auto_ptr() 50 { 51 delete pointee; 52 } 53 54 template<typename T> 55 template<typename U> 56 auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs) 57 { 58 if(this!=&rhs) 59 reset(rhs.release()); 60 return *this; 61 } 62 63 template<typename T> 64 T& auto_ptr<T>::operator*() const 65 { 66 return *pointee; 67 } 68 69 template<typename T> 70 T* auto_ptr<T>::operator->() const 71 { 72 return pointee; 73 } 74 75 template<typename T> 76 T* auto_ptr<T>::get() const 77 { 78 return pointee; 79 } 80 81 template<typename T> 82 T* auto_ptr<T>::release() 83 { 84 T* oldpointee=pointee; 85 pointee=0; 86 return oldpointee; 87 } 88 89 template<typename T> 90 void auto_ptr<T>::reset(T* p) 91 { 92 if(pointee!=p) 93 { 94 delete pointee; 95 pointee=p; 96 } 97 } 98 99 #endif
1 //Item.h 2 #ifndef ITEM_H 3 #define ITEM_H 4 5 class Item 6 { 7 public: 8 Item(void); 9 ~Item(void); 10 11 void PrintContent() const; 12 }; 13 14 #endif 15 16 //Item.cpp 17 using std::cout; 18 using std::endl; 19 20 Item::Item(void) 21 { 22 cout<<"constructor"<<endl; 23 } 24 25 Item::~Item(void) 26 { 27 cout<<"Destorying....."<<endl; 28 } 29 30 void Item::PrintContent() const 31 { 32 cout<<"Here is the content"<<endl; 33 }
#include <iostream> #include "auto_ptr.h" #include "Item.h" using std::cout; int main() { auto_ptr<Item> itemPtr(new Item); itemPtr->PrintContent(); auto_ptr<Item> itemPtr2(itemPtr); itemPtr2->PrintContent(); return 0; }