C++智能指针auto_ptr

来源:互联网 发布:linux卸载ibus 编辑:程序博客网 时间:2024/06/14 15:17

看了SGI STL的auto_ptr,感觉很奇妙,在此总结一下:

1. auto_ptr不能共享所有权,即不要让两个auto_ptr指向同一个对象指针。

    智能指针实际上是将“源对象指针”寄生于auto_ptr当中,当两个auto_ptr指向同一个对象指针时,“源对象指针”却只有一份;在两个智能指针对象相继销毁时,会delete两次“源对象指针”,系统内存管理将报错。

2. auto_ptr不能指向数组,因为auto_ptr在析构的时候只是调用delete,而数组应该要调用delete[]。

3. auto_ptr的相互拷贝、赋值都不会影响“源对象指针”,即“源对象指针”总是只有一份。

4. 当_M_ptr = 0;delete _M_ptr;是安全的,即不会做任何操作。 


不说了,直接看代码吧: 

#include <iostream>using namespace std;#define __STL_NOTHROW throw()template <class _Tp> class auto_Ptr {private:  _Tp* _M_ptr;public:  typedef _Tp element_type;  //构造函数,将“源对象指针”赋予(寄生)于智能指针  explicit auto_Ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p)   {    cout<<"auto_Ptr(_Tp* __p = 0)"<<endl;  }  //拷贝构造函数,在__a.release()中进行了浅拷贝,  auto_Ptr(auto_Ptr& __a) __STL_NOTHROW : _M_ptr(__a.release())   {    cout<<"auto_Ptr(auto_Ptr& __a)"<<endl;  }  //赋值函数  auto_Ptr& operator=(auto_Ptr& __a) __STL_NOTHROW   {    cout<<"operator=(auto_Ptr& __a)"<<endl;    if (&__a != this) {      delete _M_ptr;      _M_ptr = __a.release();    }    return *this;  }  //析构函数  ~auto_Ptr()   {     cout<<"~auto_Ptr() "<<endl;    delete _M_ptr;     //The C++ language guarantees that delete p will do nothing if p is equal to NULL.//如果_M_ptr = 0, delete _M_ptr将不会做任何操作。  }  _Tp& operator*() const __STL_NOTHROW   {    return *_M_ptr;  }  //当使用智能指针对象->时,实际是“源对象指针”->  _Tp* operator->() const __STL_NOTHROW   {    return _M_ptr;  }  _Tp* get() const __STL_NOTHROW   {    return _M_ptr;  }  //  _Tp* release() __STL_NOTHROW   {    _Tp* __tmp = _M_ptr;    _M_ptr = 0;//这里很重要,删除0值是安全的    return __tmp;  }  void reset(_Tp* __p = 0) __STL_NOTHROW   {    if (__p != _M_ptr) {      delete _M_ptr;      _M_ptr = __p;    }  }};class Report{private:  char* str;public:  Report(char* s):str(s)  {    cout<<"Object created !"<<endl;  }  ~Report()  {    cout<<"Object deleted"<<endl;  }  void comment() const   {    cout<<str<<endl;  }};//基本操作void test(){  auto_Ptr<Report> ptr(new Report("using auto_Ptr"));  ptr->comment();    Report *r = new Report("using auto_Ptr");  auto_Ptr<Report> ptr2(r);  //r和ptr2都可以调用comment,是因为智能指针的operator->返回指针r  r->comment();  ptr2->comment();}//对智能指针进行new,智能指针需要手动释放deletevoid test1(){   Report *r = new Report("using auto_Ptr");  auto_Ptr<Report> *ptr  = new auto_Ptr<Report>(r);  r->comment();  (*ptr)->comment();//通过对象调用->  delete ptr;}//不同智能指针共享同一个源对象指针,程序将crashvoid test2(){  Report *r = new Report("using auto_Ptr");  auto_Ptr<Report> ptr(r);    auto_Ptr<Report> ptr2(r);    }//不管智能指针怎么相互拷贝,“源对象指针”只有一份//在析构删除“源对象指针”时,第一次正常删除,第二次delete 0。void test3(){  Report *r = new Report("using auto_Ptr");  auto_Ptr<Report> ptr(r);    auto_Ptr<Report> ptr2(ptr);}//赋值操作,不管智能指针怎么相互赋值,“源对象指针”只有一份//在析构删除“源对象指针”时,第一次正常删除,第二次delete 0。void test4(){  Report *p = new Report("using auto_Ptr");  auto_Ptr<Report> ps(p);    auto_Ptr<Report> ps2;  ps2 = ps;  }int main(){  //test();  //test1();  test2();  //test3();  //test4();}


0 0