Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > 从MFC中的CSinpleList学到的东西
【标  题】:从MFC中的CSinpleList学到的东西
【关键字】:MFC,CSinpleList
【来  源】:http://blog.csdn.net/jones2000/archive/2006/07/29/995980.aspx

从MFC中的CSinpleList学到的东西

Your Ad Here

stock是一种先进后出(First in last out)的数据结构,queue是一种先进先出(first in first out)的数据结构,在stl中实现方法是用了把deque双向队列封装了一下(具体可以查看<<stl源妈解析>>大概是第4章).
今天剥离MFC中CWinThread的类时,发现是一个MFC存放线程信息的一个队列类CSimpleList,是个队列的类和我以前看到的方法都不一样它用了位移来得到p->next(比较牛啊).具体代码我从MFC中剥离了出来,根据这种想法我又写了stock和queue的两个类,其实是想写list的嫌麻烦,就改简单的了.重在思想.

先给出 CSimpleList代码

Simplelist.h
#ifndef __JONES__CSIMPLELIST__
#define __JONES__CSIMPLELIST__

class CSimpleList
{
public:
 CSimpleList(int nNextOffset = 0);
 void Construct(int nNextOffset);

//操作
 BOOL IsEmpty() const;
 void AddHead(void* p);
 void RemoveAll();
 void* GetHead() const;
 void* GetNext(void* p) const;
 BOOL Remove(void* p);
 void** GetNextPtr(void* p) const;

private:
 void* m_pHead;
 size_t m_nNextOffset;  //pNext的位移偏量

};

//对CSimpleList的一个封装
template<class TYPE>
class CTypedSimpleList : public CSimpleList
{
public:
 CTypedSimpleList(int nNextOffset = 0)
  : CSimpleList(nNextOffset) { }
 void AddHead(TYPE p)
  { CSimpleList::AddHead(p); }
 TYPE GetHead()
  { return (TYPE)CSimpleList::GetHead(); }
 TYPE GetNext(TYPE p)
  { return (TYPE)CSimpleList::GetNext(p); }
 BOOL Remove(TYPE p)
  { return CSimpleList::Remove((TYPE)p); }
 operator TYPE()
  { return (TYPE)CSimpleList::GetHead(); }
};

#endif

#include "stdafx.h"
#include "SimpleList.h"

CSimpleList::CSimpleList(int nNextOffset)
{
 m_pHead = NULL;
 m_nNextOffset = nNextOffset;
}

void CSimpleList::Construct(int nNextOffset) 
{
 assert(m_pHead == NULL);
 m_nNextOffset = nNextOffset;
}

BOOL CSimpleList::IsEmpty() const
{
 return m_pHead == NULL;
}


void** CSimpleList::GetNextPtr(void* p) const
{
 assert(p != NULL);
 return (void**)((BYTE*)p+m_nNextOffset);  
//重点啊 配合下面的g_list.Construct(offsetof(CThreadData, pNext)); 一起看,然后画个图 是不是得到是pNext的位置
}


void CSimpleList::RemoveAll()
{
 m_pHead = NULL;
}


void* CSimpleList::GetHead() const
{
 return m_pHead;
}

void* CSimpleList::GetNext(void* prevElement) const
{
 return *GetNextPtr(prevElement);
}

void CSimpleList::AddHead(void* p)
{
 assert(p != NULL);
 assert(*GetNextPtr(p) == NULL);

 *GetNextPtr(p) = m_pHead;
 m_pHead = p;
}

BOOL CSimpleList::Remove(void* p)
{
 assert(p != NULL);

 if (m_pHead == NULL)
  return FALSE;

 BOOL bResult = FALSE;
 if (m_pHead == p)
 {
  m_pHead = *GetNextPtr(p);
  bResult = TRUE;
 }
 else
 {
  void* pTest = m_pHead;
  while (pTest != NULL && *GetNextPtr(pTest) != p)
   pTest = *GetNextPtr(pTest);
  if (pTest != NULL)
  {
   *GetNextPtr(pTest) = *GetNextPtr(p);
   bResult = TRUE;
  }
 }
 return bResult;
}

//调用了

struct CThreadData
{
 CThreadData* pNext; 
 int nCount;        
 LPVOID* pData;     
};


CTypedSimpleList<CThreadData*> g_list;
int main(int argc, char* argv[])
{
 g_list.Construct(offsetof(CThreadData, pNext)); //得到pNext的和CThreadData的偏量
 CThreadData* pData=NULL,
 pData = new CThreadData;
 pData->nCount = 0;
 pData->pData = NULL;
 pData->pNext=NULL;
 g_list.AddHead(pData);

 pData = new CThreadData;
 pData->nCount = 1;
 pData->pData = NULL;
 pData->pNext=NULL;
 g_list.AddHead(pData);

 pData = new CThreadData;
 pData->nCount = 2;
 pData->pData = NULL;
 pData->pNext=NULL;
  
 g_list.AddHead(pData);

 pData=g_list;
 while(pData=g_list.GetNext(pData))
 {
      printf("%d\r\n",pData->nCount);
 }
..................................delete掉new出来的东西(略) 可以调Remove() 然后delete
}

 

//下面是我自己根据这个原理写的stock和queue 最后用模版封装了一下

#ifndef __JONES_QUEUE__STOCK
#define __JONES_QUEUE__STOCK

class ListBase //list基类
{
public:
 void Construct(int nNextOffset); //pNext的位移

protected:
 void** GetNextPtr(void* p) const; //利用位移得到pNext地址
 size_t m_nNextOffset; //偏移量
};


/********************************************************************/
/******************QueueList 先进先出********************************/
/********************************************************************/
class QueueList : public ListBase
{
public:
 QueueList(int nNextOffset=0);

//操作
 bool empty() const;
 void* front() const; //得到栈的第一个数据
 void pop(); //出栈
 void push(void* p); //压栈
private:
 void* m_pHead; //头
 void* m_pTail; //尾
};


/********************************************************************/
/******************StockList 先进后出********************************/
/********************************************************************/
class StockList : public ListBase
{
public:
 StockList(int nNextOffset=0);
 void pop(); //出栈
 void push(void* p); //压栈
 void* front() const; //得到栈的第一个数据
private:
 void* m_pHead; //头
};

/********************************************************************/
/*封装了一下 好看点而已(起码也用到模版了,现在流行的技术,呵呵.....) */
/********************************************************************/
template <typename TYPE,typename LISTTYPE=QueueList /*list类型*/>
class SpecialList : public LISTTYPE
{
public:
 SpecialList(int nNextOffset=0)
  : LISTTYPE(nNextOffset)  {}

 TYPE front()
  { return (TYPE)LISTTYPE::front(); }

 void push(TYPE p)
  { LISTTYPE::push(p); }

};
#endif

//调用的例子
struct CThreadData
{
 CThreadData* pNext; 
 int nCount;     
 LPVOID* pData; 
};

SpecialList<CThreadData*,QueueList> g_Queue;

int main(int argc, char* argv[])

 g_Queue.Construct(offsetof(CThreadData, pNext));
 CThreadData* pData=NULL,*pTemp=NULL;
 pData = new CThreadData;
 pData->nCount = 0;
 pData->pData = NULL;
 pData->pNext=NULL;
 g_Queue.push(pData);

 pData = new CThreadData;
 pData->nCount = 1;
 pData->pData = NULL;
 pData->pNext=NULL;
 g_Queue.push(pData);

 pData = new CThreadData;
 pData->nCount = 2;
 pData->pData = NULL;
 pData->pNext=NULL; 
 g_Queue.push(pData);

 while(pData=g_Queue.front())
 {
  printf("%d\r\n",pData->nCount);
  g_Queue.pop();
  delete pData;
 }
 
  return 0;
}

最后忘了说还有1点就是 如果你用的是继承的数据
class CNoTrackObject
{
public:
 virtual ~CNoTrackObject() {};

};

struct CThreadData : public CNoTrackObject
{
 CThreadData* pNext;
 int nCount;        
 LPVOID* pData;     )
};

那pNext位移的偏量就不是0了是4,具体可以查看<<c++对象模型>>

好写完了,今天本打算去从MFC里剥离CWinThread的类看来是不行了,里面涉及了好多全局的链表,看的头大了55555~~~ ,只能把那些链表去掉了,哎看来我的程序功底还不行啊 继续努力. 如果明天有空 就把我剥的CWinThread贴出来,里面还是有许多东西值得我们学习的~~~~~~,如果哪位大大.........虾有CWinThread剥离后的代码(包括全局的那些链表) 裸跪求360度 请发给我~~~~~~~

磨坊启动了!!:【上一篇】
(codes)active desk shortcut program:【下一篇】
【相关文章】
  • MFC功能扩展:大数运算及RSA算法库
  • MFC 中 命令消息传递 (原创)
  • MFC socket程序开发
  • 深入分析MFC中的CArray类(转载)
  • My Understanding of MFC serialization
  • 使MFC变漂亮一:MFC与Flash交互示例
  • 使MFC变漂亮二:MFC与HTML交互示例
  • 简述VC/MFC下窗口的拖放
  • 用MFC实现串口编程
  • Programming Windows with MFC - Capter 10. Scroll Views, HTML Views, and Other View Types
  • 【随机文章】
  • 间谍软件假仁假义 下载程序要当心
  • storage vendor
  • Vopt99另类破解实战录
  • 基于IntelPXA255平台的网络摄像机设计
  • C++编程常见的内存错误及其对策
  • 小技巧带来方便
  • 各品牌网址技术支持联系方式一览
  • 欢迎进入★雪た域ζ雄ど鹰★ 博客!
  • outlook无法记忆密码
  • NETCF开发之POOM应用开发——简介
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.