模板類-安全鏈表 SafeList

模板類-安全鏈表 SafeList

本文旨在說明:
對: CPtrList CMap 之類的進行安全處理.


曾經有個好友, 對CMap 封裝了, 實現了安全map.
我就封裝了CPtrList, 實現了安全鏈表


1. 聲明, 重要實現
template <class T>
class DAVECMNLIB_CLASS CDVSafePtrList : public CPtrList

最重要的代碼:

virtual ~CDVSafePtrList()
 {
  ClearAll();
 }

 
virtual void ClearAll()
 {
  
while( GetCount() )
  {
   T
* p = GetHead();
   RemoveHead();
   safe_delete( p );
  }
 }

 


2. 曾經的錯誤
我記得我在很久以前, 這裏的處理是:

void* p = RemoveHead();
if( p ) 
{
  delete p;
 p 
= NULL;
}

void* p, 是因爲CPtrList 默認的指針對象的數據類型.
這樣的操作是根本沒有意義的.

void* delete  不會調用對象的析構函數.
可是還是有很多人像曾經的我一樣不知道 這一點的.


所以template  很好用. 可以轉爲真正的正確的指針對象的數據類型.
然後刪除.

 


3. 其他應用
這樣的我就實現了: CDVSafePtrList<T>
後來我做了一個cache 類, 因爲我不知道我要cache 什麼對象.
所以還是使用template

實現利用了現有的: CDVSafePtrList< T >

template <class T>
class CDVCache : public CDVSafePtrList<T>


實現從cache 無論如何能得到對象, 有個條件: t = new T();

T* GetCacheAuto()
 {
  T
* t = GetCache(); // get existing cache object
  if!t )
   t 
= new T(); // new an object
  return t;
 };

 

4. 關於cache, 什麼是cache
cache 裏面如果數據太多, 就自動刪除老的數據.
如果數據太少, 而要取數據,就要new 一個對象.
這些其實STL 早有核心的實現.
而我只是爲了方便. 自己美化一下而已.
而且這樣的實現也沒有考慮到多線程調度的安全性.

要寫一個很好的類, 很完美的類, 幾乎不太可能.
往往是爲了某事寫某類.

  

 

5. CDVSafePtrList<T>代碼

大家可以隨意應用以及修改代碼.

 

/*
Head Info: CDVSafePtrList Definations.

  It can delete all ptr objects when this being destory. It is a safe
 ptr list.


Author: DaveMin
Create: 2003-06-02

History:
2007-2-21 Add: GetHead, GetTail, GetNext, GetPrev, GetAt, Find, FindEx APIs.
*/


#if !defined(AFX_DVSAFEPTRLIST_H__A4E779F9_CAAD_4EF0_9CBA_AEA7041858D6__INCLUDED_)
#define AFX_DVSAFEPTRLIST_H__A4E779F9_CAAD_4EF0_9CBA_AEA7041858D6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


template 
<class T>
class DAVECMNLIB_CLASS CDVSafePtrList : public CPtrList
{
public:
 typedef T _PtrClass;

 CDVSafePtrList()
 
{};

 
virtual ~CDVSafePtrList()
 
{
  ClearAll();
 }


 
virtual void ClearAll()
 
{
  
while( GetCount() )
  
{
   T
* p = GetHead();
   RemoveHead();
   safe_delete( p );
  }

 }


 inline T
* GetAt( POSITION position )
 
{
  
return (T*) CPtrList::GetAt( position );
 }


 inline T
* GetNext( POSITION& position )
 
{
  
return (T*) CPtrList::GetNext( position );
 }

 
 inline T
* GetPrev( POSITION& position )
 
{
  
return (T*) CPtrList::GetPrev( position );
 }

 
 inline T
* GetTail()
 
{
  
return (T*) CPtrList::GetTail();
 }


 inline T
* GetHead()
 
{
  
return (T*) CPtrList::GetHead();
 }


 inline T
* RemoveHead()
 
{
  
return (T*) CPtrList::RemoveHead();
 }


 inline T
* RemoveTail()
 
{
  
return (T*) CPtrList::RemoveTail();
 }


 inline BOOL Remove( 
void* p )
 
{
  POSITION pos 
= CPtrList::Find( p );
  
if( pos )
  
{
   CPtrList::RemoveAt( pos ); 
   
return TRUE;
  }

  
return FALSE;
 }


 inline BOOL RemoveT( T
* p )
 
{
  
return Remove( p );
 }


 inline BOOL Remove( DWORD dwData )
 
{
  
return Remove( (void*)dwData );
 }

 
 
//
 
// the original API
 inline POSITION Find(void* searchValue, POSITION startAfter = NULL)
 
{
  
return CPtrList::Find( searchValue, startAfter);
 }


 
// the Extension API
 inline POSITION Find(DWORD dwData, POSITION startAfter = NULL)
 
{
  
return CPtrList::Find( (void*)dwData, startAfter);
 }

 
 
//
 
// the Extension API, and find the object directly
 T* FindEx(DWORD dwData, POSITION startAfter = NULL, T* pReturnNullValue = NULL)
 
{
  POSITION pos 
= CPtrList::Find( (void*)dwData, startAfter);
  
if( pos )
  
{
   
return GetAt( pos );
  }

  
return pReturnNullValue;
 }



 
void MoveTo( CDVSafePtrList<T>& ptrList, int index = 0int count = -1 )
 

  
int ininIndex = index;
  
while( TRUE )
  
{
   POSITION pos 
= FindIndex( ininIndex ); 
   
if!pos )
    
break;

   POSITION posOld 
= pos;
   T
* p = GetNext( pos );

   ptrList.AddTail( p );
   RemoveAt( posOld );

   
if++ index == count )
    
break;
  }

 }

}
;

#endif // !defined(AFX_SAFEPTRLIST_H__A4E779F9_CAAD_4EF0_9CBA_AEA7041858D6__INCLUDED_)



 

 

歡迎加入VC技術羣: 30107096

 

 

 

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