智能指针(上)

#define_CRT_SECURE_NO_WARNINGS1

//AutoPtr(新方案)

#include

usingnamespacestd;

template <classT>

classAutoPtr

{

public:

      AutoPtr(T* ptr)

           :_ptr(ptr)

      {}

      AutoPtr(AutoPtr<T>&ap)

           :_ptr(ap._ptr)

      {

           ap._ptr= NULL//交换管理权,将ap1置空

      }

      AutoPtr <T>&operator=(AutoPtr<T>&ap)

      {

           if(this != &ap)    //防止自赋值

           {

                 delete_ptr; //删除空间(不让指针指向自己的空间)

                 _ptr= ap._ptr; //管理权转移(相当于ap3指向了ap2

                 ap._ptr= NULL; //置空(ap2

           }

           return*this;

      }

      T& operator*()

      {

           return*_ptr;

      }

      T* operator->()

      {

           return_ptr;

      }

      ~AutoPtr()

      {

           if(_ptr)

           {

                 cout<< "delete:"<< _ptr << endl;

                 delete_ptr;

                 _ptr= NULL;

           }

      }

protected:

      T* _ptr;

};

structA

{

      int_a;

};

int main()

{

      AutoPtr<int>ap1(newint(1));

      AutoPtr<int>ap2(ap1);

      AutoPtr<int>ap3(newint(2));

      ap3 =ap2;

      *ap3 =1;

      AutoPtr<A>ap4(newA);

      ap4->_a= 6;

      return0;

}

 

//ScopedPtr:守卫指针

#include

usingnamespacestd;

template<classT>

classScopedPtr

{

public:

      ScopedPtr(T* ptr)

           :_ptr(ptr)

      {}

      ~ScopedPtr()

      {

           if(_ptr)

           {

                 cout<< "delete:"<< _ptr << endl;

                 delete_ptr;

           }

      }

      T& operator*()

      {

           return*_ptr;

      }

      T* operator->()

      {

           return_ptr;

      }

protected//防拷贝,防止函数被在类外实现

      ScopedPtr(ScopedPtr<T>&sp);  //只声明不实现

      ScopedPtr<T>&operator=(ScopedPtr<T>&sp);

protected:

      T* _ptr;

};

structA

{

      int_a;

};

int main()

{

      ScopedPtr<int>sp1(newint(1));

      //ScopedPtrsp2(sp1);

      *sp1 =1;

      ScopedPtr<A>sp2(newA);

      sp2->_a= 5;

      return0;

}

  

//SharedPtr(共享指针)

#include

usingnamespacestd;

template<classT>

classSharedPtr

{

public:

      SharedPtr(T* ptr)

           :_ptr(ptr)

           ,_pcount(newint(1))

      {}

      ~SharedPtr()

      {

           if(--(*_pcount) == 0)

           {

                 delete_ptr;

                 delete_pcount;

           }

      }

      SharedPtr(constSharedPtr<T>&sp)

           :_ptr(sp._ptr)

           ,_pcount(sp._pcount)  //两个指针指向同一块空间

      {

           ++(*_pcount);     //计数加1

      }

      SharedPtr<T>&operator=(constSharedPtr<T>& sp)

      {

           if(_ptr != sp._ptr)  //1)防止自赋值;(2)两个指针管理同一块空间

           {

                 if(--(*_pcount) == 0)  //3)两个指针分别指向两块空间时

                 {

                      delete_ptr;

                      delete_pcount;

                 }

                 _ptr= sp._ptr;

                 _pcount= sp._pcount;

                 ++(*_pcount);

           }

           return*this;

      }

      T& operator*()

      {

           return*_ptr;

      }

      T* operator->()

      {

           return_ptr;

      }

protected:

      T* _ptr;

      int*_pcount;  //计数指针

};

structA

{

      int_a;

};

int main()

{

      SharedPtr<int>sp1(newint(1));

      SharedPtr<int>sp2(sp1);

      SharedPtr<int>sp3(sp2);

      SharedPtr<int>sp4(newint(2));

      sp1 =sp4;

      *sp4 =6;

      SharedPtr<A>sp5(newA);

      sp5->_a= 5;

      return0;

}


智能指针(下)

//1.AutoPtr的另一种写法。(旧方案)

#include

usingnamespacestd;

template<classT>

classAutoPtr

{

public:

      AutoPtr(T* ptr)

           :_ptr(ptr)

           ,_owner(true)

      {}

      ~AutoPtr()

      {

           if(_owner)  //只要_owner为真,则析构

           {

                 delete_ptr;

           }

      }

      AutoPtr(AutoPtr<T>&ap)

           :_ptr(ap._ptr)

      {

           ap._owner= false;

      }

      AutoPtr<T>&operator=(AutoPtr<T>&ap)

      {

           if(this != &ap)

           {

                 _ptr= ap._ptr;

                 ap._owner= false;

           }

           return*this;

      }

      T& operator*()

      {

           return*_ptr;

      }

      T* operator->()

      {

           return_ptr;

      }

protected:

      T* _ptr;

      bool_owner;

};

structA

{

      int_a;

};

int main()

{

      AutoPtr<int>ap1(newint(1));

      AutoPtr<int>ap2(ap1);

      AutoPtr<int>ap3(newint(2));

      ap3 =ap2;

      *ap3 =10;

      AutoPtr<A>ap4(newA);

      ap4->_a= 20;

      return0;

}

//AutoPtr虽然存在问题,但是不能废除,因为存在兼容性问题,要保证之前的代码还可以兼容。尽量不要使用就好。

//Question:新方案和旧方案哪个更好?

//答:新方案较好。(1)旧方案占的内存大于新方案;(2)旧方案的每个指针变量的值都可以修改,不安全;(3)当出现

//以下情况时新方案优于旧方案

//AutoPtr ap1(new int(1));

//if (xxx)

//{

//    AutoPtrap2(ap1);

//}

//ap1拷贝构造出ap2时,ap1_ownerfalseap2_ownertrue;但是当ap2出了作用域后会发生析构,此时若使用*ap1*

//的方式修改ap1的值时,会出现野指针(垂悬指针)的问题,导致程序出现错误。

 


//定置删除器

#include

#include

usingnamespacestd;

 

struct Free

{

      voidoperator()(void* ptr)

      {

           cout<< "Free" << ptr<< endl;

           free(ptr);

      }

};

 

void TestSharedPtr()

{

      int*p1 = (int*)malloc(sizeof(int)*10);

      shared_ptr<int>sp(p1, Free());

      /*FILE*p2 = fopen("test.txt", "r");

      shared_ptrsp2(p2);*/

}


//仿函数(,重载了operator[],不是函数像函数)

template<classT>

structLess

{

      booloperator()(constT&l,constT& r)

      {

           returnl< r;

      }

};

int main()

{

      TestSharedPtr();

      //Lessless;

      //cout<< less(1, 2) << endl;

      return0;

}


//2.模拟SharedPtr的定置删除器

#include

usingnamespacestd;

 

template<classT>

structDefaultDel  //默认删除器

{

      voidoperator()(T* ptr)

      {

           deleteptr;

      }

};

template<classT,classD=DefaultDel<T>>

classSharedPtr

{

public:

      SharedPtr(T* ptr)

           :_ptr(ptr)

           ,_pcount(newint(1))

      {}

      SharedPtr(T* ptr,Ddel)

           :_ptr(ptr)

           ,_pcount(newint(1))

           ,_del(del)

      {}

      ~SharedPtr()

      {

           _Release();

      }

      SharedPtr(constSharedPtr<T,D>& sp)

           :_ptr(sp._ptr)

           ,_pcount(sp._pcount)  //两个指针指向同一块空间

      {

           ++(*_pcount);     //计数加1

      }

      SharedPtr<T, D>& operator=(constSharedPtr<T, D>& sp)

      {

           if(_ptr != sp._ptr)  //1)防止自赋值;(2)两个指针管理同一块空间//3)两个指针分别指向两块空间时

           {

                 _Release();

                 _ptr= sp._ptr;

                 _pcount= sp._pcount;

                 ++(*_pcount);

           }

            return *this;

      }

      T& operator*()

      {

           return*_ptr;

      }

      T* operator->()

      {

           return_ptr;

      }

      T* GetPtr()

      {

           return_ptr;

      }

protected:

      void_Release()

      {

           if(--(*_pcount) == 0)

           {

                 /*delete_ptr;*/

                 _del(_ptr);

                 delete_pcount;

           }

      }

protected:

      T* _ptr;

      int*_pcount;  //计数指针

      D _del;

};

 

template<classT>

structFree

{

      voidoperator()(T* ptr)

      {

           free(ptr);

      }

};

void TestDeleter()

{

      SharedPtr<int, DefaultDel<int>>sp1(newint(1));

      SharedPtr<int, Free<int>>sp2((int*)malloc(sizeof(int)));

      SharedPtr<int>sp3(newint(1));

}

int main()

{

      return0;

}


//3.学习定置删除器和循环引用的场景并理解

//循环引用

#include

#include

usingnamespacestd;

 

void Test()

{

      shared_ptr<int>sp1(newint(1));

      shared_ptr<int>sp2(sp1);

      cout<< "sp1:"<< sp1.use_count()<< endl;

      cout<< "sp2:"<< sp2.use_count()<< endl;

}

structNode

{

      shared_ptr<Node>_next;

      shared_ptr<Node>_prev;

      ~Node()

      {

           cout<< "delete:"<<this<< endl;

      }

};

void TestSharedPtr()

{

      shared_ptr<Node>cur(newNode());

      shared_ptr<Node>next(newNode());

      cur->_next= next;

      next->_prev= cur;   //析构时会相互等待(curnext

}

int main()

{

      /*Test();*/

      TestSharedPtr();

      getchar();

      return0;

}

 

 

//循环引用的解决

//weak_ptr打破了循环,不增加引用计数,也重载operator*/operator->

#include

#include

usingnamespacestd;

 

void Test()

{

      shared_ptr<int>sp1(newint(1));

      shared_ptr<int>sp2(sp1);

      cout<< "sp1:" << sp1.use_count()<< endl;

      cout<< "sp2:" << sp2.use_count()<< endl;

}

structNode

{

      weak_ptr<Node>_next; 

      weak_ptr<Node>_prev;

      ~Node()

      {

           cout<< "delete:"<< this << endl;

      }

};

void TestSharedPtr()

{

      shared_ptr<Node>cur(newNode());

      shared_ptr<Node>next(newNode());

      cout<< "cur:" << cur.use_count()<< endl;

      cout<< "next:"<< next.use_count() << endl;

      cur->_next= next;

      next->_prev= cur; 

      cout<< "赋值后:" << endl;

      cout<< "cur:" << cur.use_count()<< endl;

      cout<< "next:"<< next.use_count() << endl;

}

int main()

{

      /*Test();*/

      //TestSharedPtr();

      shared_ptr<int> sp(newint(10));

      weak_ptr<int>wp(sp);

      getchar();

      return0;

}