模板類-安全鏈表 SafeList
本文旨在說明:
對: CPtrList CMap 之類的進行安全處理.
曾經有個好友, 對CMap 封裝了, 實現了安全map.
我就封裝了CPtrList, 實現了安全鏈表
1. 聲明, 重要實現
template <class T>
class DAVECMNLIB_CLASS CDVSafePtrList : public CPtrList
最重要的代碼:
{
ClearAll();
}
virtual void ClearAll()
{
while( GetCount() )
{
T* p = GetHead();
RemoveHead();
safe_delete( p );
}
}
2. 曾經的錯誤
我記得我在很久以前, 這裏的處理是:
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* 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 = 0, int 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