模板类-安全链表 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