智能指標(帶有效性檢查功能)

來源:互聯網
上載者:User

大概朋友們的一看到這個貼子的第一個感覺就是:又有閑得無聊 的傢伙在造輪子了。
 呃,坦白的說,的確是這樣。^_^
就算STL中的auto_ptr的所有權轉移是不可接受的方案,那BOOST庫中的雖說不太靈活,但用用也夠了吧?再怎麼吹毛求齜,LOKI庫中的智能指標還不能滿足要求嗎?什嗎?要包含的標頭檔太多讓你不爽?你分明是找碴!
以下純屬手閑得慌的結果,待會兒繼續讀LOKI去。

//以下是我的輪子 VC2003下通過
//////////////////////////////////////////////////////////////////////
//
// class name:
//  autoptr
// description:
//  autoptr is a light weight smart pointer. It can remember all pointers
//  that have pointed to a object, and auto delete when no other pointers
//  point to the object.
//  Function Reset() means don't let the autoptr point to the object,
//  If it's the last point, the object will be deleted.
//  If require autoptr report pointer's validation, declaration should be:
//   autoptr<int, NotArray<int>, ExceptionInvalidPointer<int> > pX(new int);
//  Then if the internal pointer is NULL, and calls "pX->" or "*pX", it will
//  throw an string of type char* indentify the name of type T.
// author:
//  sproll
// date:
//  07-02-09
//
//////////////////////////////////////////////////////////////////////

#pragma once

#include <typeinfo.h>

template <typename T>
class NotArray
{
public:
 NotArray(T* pt) : m_pt(pt){};
 ~NotArray(){};
 void Del(){delete m_pt;};
 T& Get(unsigned int uIndex)
 {
  if (uIndex != 0)
  {
   char* pcBuf = "operator [] on pointer which is not array.";
   throw pcBuf;
  }
  else
  {
   return *m_pt;
  }
 };
private:
 T* m_pt;
};

template <typename T>
class IsArray
{
public:
 IsArray(T* pt) : m_pt(pt){};
 ~IsArray(){};
 void Del(){delete [] m_pt;};
 T& Get(unsigned int uIndex){return m_pt[uIndex];};
private:
 T* m_pt;
};

template <typename T>
class NoException
{
public:
 void CheckValid(void* p){};
};

template <typename T>
class ExceptionInvalidPointer
{
public:
 ExceptionInvalidPointer()
  : m_pstrName(typeid(T).name())
 {
 };
 ExceptionInvalidPointer(const ExceptionInvalidPointer<T>& copy)
  : m_pstrName(typeid(T).name())
 {
 };
 ~ExceptionInvalidPointer(){};

 void CheckValid(T* p)
 {
  if (p == NULL)
  {
   char *pName = new char[strlen(m_pstrName) + 1];
   strcpy(pName, m_pstrName);
   throw pName;
  }
 };

private:
 const char* m_pstrName;
};

template <typename T, typename ArrayCheck = NotArray<T>, typename ValidCheck = NoException<T> >
class autoptr
{
public:
 autoptr() : m_pT(NULL), m_pnRefCount(NULL){};
 autoptr(T* pT) : m_pT(pT), m_pnRefCount(pT? new int : NULL){if (m_pnRefCount) *m_pnRefCount = 1;};
 autoptr(autoptr<T, ArrayCheck, ValidCheck>& ptr) : m_pT(ptr.m_pT), m_pnRefCount(ptr.m_pnRefCount) {if(m_pnRefCount) ++(*m_pnRefCount);};
 ~autoptr() {Reset();};

 autoptr<T, ArrayCheck, ValidCheck>& operator= (autoptr<T, ArrayCheck, ValidCheck>& ptr);
 T* operator-> () {ValidCheck chk; chk.CheckValid(m_pT); return m_pT;};
 T& operator* () { ValidCheck chk; chk.CheckValid(m_pT); return *m_pT;};
 bool operator==(const autoptr<T, ArrayCheck, ValidCheck>& ptr) const {return ptr->m_pT == m_pT;};
 bool operator!=(const autoptr<T, ArrayCheck, ValidCheck>& ptr) const {return ptr->m_pT != m_pT;};
 T& operator [] (unsigned int nIndex) {ArrayCheck arrchk(m_pT); return arrchk.Get(nIndex);};

 //remove this auto_ptr from reference counting
 void Reset();
 //check if valid
 bool Valid(){return m_pT != NULL;};

private:
 //the object that is pointed
 T* m_pT;
 //reference count
 int* m_pnRefCount;
};

template <typename T, typename ArrayCheck, typename ValidCheck>
autoptr<T, ArrayCheck, ValidCheck>& autoptr<T, ArrayCheck, ValidCheck>::operator= (autoptr<T, ArrayCheck, ValidCheck>& ptr)
{
 if (this == &ptr)
 {
  return *this;
 }

 Reset();

 m_pT = ptr.m_pT;
 m_pnRefCount = ptr.m_pnRefCount;
 if (m_pnRefCount)
 {
  ++(*m_pnRefCount);
 }

 return *this;
}

template <typename T, typename ArrayCheck, typename ValidCheck>
void autoptr<T, ArrayCheck, ValidCheck>::Reset()
{
 if (m_pnRefCount)
 {
  if (*m_pnRefCount == 1)
  {
   if (m_pT)
   {
    ArrayCheck arrchk(m_pT);
    arrchk.Del();
    m_pT = NULL;
   }
   if (m_pnRefCount)
   {
    delete m_pnRefCount;
    m_pnRefCount = NULL;
   }
  }
  else if (*m_pnRefCount > 1)
  {
   (*m_pnRefCount)--;
   
   m_pT = NULL;
   m_pnRefCount = NULL;
  }
 }
}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.