1、auto_ptr<T>解决什么问题?
在堆上获取的资源,客户可能会忘记delete,或者由于异常没有执行到delete,导致资源泄漏。在栈上分配的对象,有个特点,不论出现什么情况,超出作用域后,都将调用析构方法。根据这个特点,可以使用栈上的对象管理指针,析构的时候执行delete,确保一定释放资源。
2、auto_ptr就是解决这个问题的,auto_ptr就是个资源管理类,它的特点是拥有权转移。
3、考虑,如果让我来设计auto_ptr,我该怎么做?
auto_ptr是个资源管理类,对指针封装。有几点需要注意:
a、可以对不同类型的指针进行封装,因此需要一个模板类。
b、copy构造,copy赋值的时候,对拥有权转移。
c、考虑到,不同资源管理类之间的兼容,比如将auto_ptr<Dog>对象赋值给auto_ptr<Animal>,对于copy构造和copy赋值,需要添加对应的模版成员方法。
d、要让资源管理类,行为像一个指针,因此要重载操作符*,->,它们不改变对象内容,声明为const成员方法。
e、为了与其它接口兼容,资源管理类必须提供接口get(),暴露内部资源,get()不改变对象内容,声明为const成员方法。
f、最重要的,析构方法执行delete。
4、示例代码如下:
1 template2 class auto_ptr 3 { 4 public: 5 auto_ptr(T* ptr):_ptr(ptr) 6 { 7 } 8 9 auto_ptr(auto_ptr & rhs)10 {11 _ptr = rhs._ptr;12 rhs._ptr = 0;13 }14 15 auto_ptr& operator=(auto_ptr & rhs)16 {17 if(this != &rhs)18 {19 this->_ptr = rhs._ptr;20 rhs._ptr =0;21 }22 return *this;23 }24 25 26 template 27 auto_ptr (auto_ptr & rhs)28 {29 _ptr = rhs._ptr;30 rhs._ptr = 0;31 }32 33 template 34 auto_ptr & operator=(auto_ptr & rhs)35 {36 if(this != &rhs)37 {38 this->_ptr = rhs._ptr;39 rhs._ptr =0;40 }41 return *this;42 } 43 44 T& operator*() const45 {46 return *_ptr;47 }48 49 T* operator->() const50 {51 return _ptr;52 }53 54 T* get() const55 {56 return _ptr;57 }58 59 ~auto_ptr()60 {61 delete _ptr;62 }63 64 private:65 T* _ptr;66 67 friend class auto_ptr;68 };
5、特别注意:上面为什么加上 friend class auto_ptr?
在C++中,private成员只能在当前类中访问,只有两层含义:this指针可以访问private成员,同一类型的rhs可以访问private成员。如果rhs和this指针不是同一个类型,不能访问rhs 的private成员。在上面的模版成员方法中,rhs 是另一个类型,为了能访问它的private成员,需要说明auto_ptr之间都是friend,这样才能访问rhs 的private成员。