分享
 
 
 

从MFC中的CSinpleList学到的东西

王朝other·作者佚名  2007-07-04
窄屏简体版  字體: |||超大  

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度 请发给我~~~~~~~

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有