智能指針

智能指針(上)

#define_CRT_SECURE_NO_WARNINGS1

//AutoPtr(新方案)

#include<iostream>

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<iostream>

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));

      //ScopedPtr<int>sp2(sp1);

      *sp1 =1;

      ScopedPtr<A>sp2(newA);

      sp2->_a= 5;

      return0;

}

  

//SharedPtr(共享指針)

#include<iostream>

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<iostream>

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<int> ap1(new int(1));

//if (xxx)

//{

//    AutoPtr<int>ap2(ap1);

//}

//ap1拷貝構造出ap2時,ap1_ownerfalseap2_ownertrue;但是當ap2出了作用域後會發生析構,此時若使用*ap1*

//的方式修改ap1的值時,會出現野指針(垂懸指針)的問題,導致程序出現錯誤。

 


//定置刪除器

#include<iostream>

#include<memory>

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_ptr<FILE>sp2(p2);*/

}


//仿函數(,重載了operator[],不是函數像函數)

template<classT>

structLess

{

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

      {

           returnl< r;

      }

};

int main()

{

      TestSharedPtr();

      //Less<int>less;

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

      return0;

}


//2.模擬SharedPtr的定置刪除器

#include<iostream>

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<iostream>

#include<memory>

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<iostream>

#include<memory>

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;

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章