C++智能指针auto_ptr

看了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,智能指针需要手动释放delete
void test1()
{ 
  Report *r = new Report("using auto_Ptr");
  auto_Ptr<Report> *ptr  = new auto_Ptr<Report>(r);
  r->comment();
  (*ptr)->comment();//通过对象调用->
  delete ptr;
}

//不同智能指针共享同一个源对象指针,程序将crash
void 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();
}


你可能感兴趣的:(C++智能指针auto_ptr)