模板类-安全链表 SafeList

来源:互联网 发布:月相手表 知乎 编辑:程序博客网 时间:2024/06/03 17:13

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