自己實現簡單的智能指針

#include<string>
#include<iostream>
using namespace std;
template<class T>
class share
{
 public:
 share():point(0){}
  share(T* p1)
  {
       point = p1;
  }
  ~share()
  {
    cout << "begin to delete share" << endl;
     if(NULL != point)
     {
      delete point;
      point = NULL;
     }
  }
  share(share& t2)
  {
      point = t2.point;
      t2.point = NULL;
  }
  share& operator =(share& t2)
  {
      point = t2.p2;
      t2.point = NULL;
      return *this;

  }
  T* operator ->()
  {
        return point;
  }
private:
   T* point;
};

class A
{
public:
   A()
   {
        n = 0;
   }
   int n;
   char v[4];

};

int main()
{
share<A>sp(new(std::nothrow) A());
sp->n = 10;

share<A>sp2 = sp;
cout << "sp2->n is :" << sp2->n << endl;
return 0;
}

輸出如下:

[root@237 code]# ./a.out 
sp2->n is :10
begin to delete share
begin to delete share



總結:
   1、這種模式是資源獨佔的,當share<A>sp2 = sp後,不允許sp再用了,因爲此時sp->point == NULL。--這種智能指針相當於std::auto_ptr;
有時會有疑問,既然是因爲:sp->point == NULL 導致sp不能用,那在 operator =()函數中,不將‘t2.point = NULL;’不就可以了。別忘了,這樣在析構時,sp跟sp2的point指向
同一塊內存,而sp->point != sp2->point(指針的數值不等,但是卻只想同一塊內存),所以會重複釋放內存。
   2、爲了防止sp=sp2後,再用sp2,可以禁止  拷貝構造函數與賦值運算符。這樣就相當於boost::scope_ptr了。


二、可以看出上面的智能指針並不好用,所以爲了解決智能指針之間既能複製又能讓不同的指針對象對同一塊內存操作,引出了用引用計數的智能指針
    (就是boost::share_ptr),代碼如下:

#include<string>
#include<iostream>
using namespace std;
template<class T>
class share
{
 public:
  share():point(0),pcount = new int(0){}
  share(T* p1)
  {
       point = p1;
	   if (pcount == NULL)
	   {   
		pcount = new int(1);   
	   }	   
  }
  ~share()
  {
    //cout << "begin to delete share" << endl;
     if(--(*pcount) == 0)
     {
      delete point;
	  delete pcount;
	  pcount = NULL;
	  cout << "begin to delete share" << endl;
      point = NULL;
     }
  }
  share(share& t2)
  {
      point = t2.point;
      t2.(*pcount)++;
	  pcount =  t2.pcount;
  }
  share& operator =(share& t2)
  {
	  if (--(*pcount) == 0)
	  {
		 delete point;   
	  }
	  point = t2.point;
      t2.(*pcount)++;
	  pcount =  t2.pcount;
      return *this;
  }
  T* operator ->()
  {
        return point;
  }
private:
   T* point;
   int* pcount; //應用計數一定是要所有的該類對象共用的  //這個引用計數在多線程下是不安全的。參考boost源碼,應該用:<span style="color: rgb(36, 39, 41); font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;">boost::detail::atomic_count</span>
};

class A
{
public:
   A()
   {
        n = 0;
   }
   int n;
   char v[4];

};

int main()
{
share<A>sp(new(std::nothrow) A());
sp->n = 10;
cout << "sp->n is :" << sp->n << endl;
share<A>sp2 = sp;
sp2->n = 20;
cout << "sp->n is :" << sp2->n << endl;
return 0;
}


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