void*不能替代叠代器和WINDOWS中的空结构体指针吗

huanglin03 2015-06-16 03:16:28
STL库中的迭代器,WINDOWS中的空结构体指针,都是为模板类而专做的各种奇巧淫技,就直接用void*指针,不是更好吗,这样,写个模板类,不用一点的再额外声明其它的东西,不论是遍历还是执行插入操作,都可以在内部将void*指针再转换出来,难道不是更简单吗?
...全文
161 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2015-06-17
  • 打赏
  • 举报
回复
引用 8 楼 bug1190 的回复:
修改两处BUG 马上就好
迭代器的设计思想是模拟原始类型的迭代操作,这样算法可以统一设计,比如

int a[] = { 1, 2, 3, 4, 5 };
std::find(a, a + 5, 3);
 
std::vector<int> b(5, 3);
std::find(b.begin(), b.end(), 3);
std::find 能够同时对原始数组和STL容器进行操作,都是靠迭代器的设计模拟了原始指针的行为。 而你的代码只不过是提供了一个遍历的方法而已,根本没做到迭代器所完成的功能,没办法在这基础上设计统一的算法
www_adintr_com 2015-06-17
  • 打赏
  • 举报
回复
迭代器的设计思想是模拟原始类型的迭代操作,这样算法可以统一设计,比如

	int a[] = { 1, 2, 3, 4, 5 };
	std::find(a, a + 5, 3);

	std::vector<int> b(5, 3);
	std::find(b.begin(), b.end(), 3);
std::find 能够同时对原始数组和STL容器进行操作,都是靠迭代器的设计模拟了原始指针的行为。 而你的代码只不过是提供了一个遍历的方法而已,根本没做到迭代器所完成的功能,没办法在这基础上设计统一的算法
huanglin03 2015-06-17
  • 打赏
  • 举报
回复
引用 12 楼 iyomumx 的回复:
说好的void*呢楼主?
眼真瞎,看代码的最上边
iyomumx 2015-06-17
  • 打赏
  • 举报
回复
说好的void*呢楼主?
huanglin03 2015-06-17
  • 打赏
  • 举报
回复
引用 10 楼 ID870177103 的回复:
代码写的不错,但不接轨 C++11支持列表枚举for (It i : a) *i ;这样的写法 而你的代码得写成

TYPE i ;
if (a.gethead (i)) { //为什么gethead没有返回p,为了调用getnext还得调用一次find
  i ;
  PVOID p = a.find (i ,NULL) ; 
  while (a.getnext (p ,i) ) {
    i ;
  }
}
乱用引用也是蛋疼的地方,用指针啊 还是谦虚一点吧
满足你的要求,全部改好,完美实现:


#pragma once

typedef void* PNODE;
//-----------------------------------------------------------------------------

template<class TYPE> 
class CXList
{	
protected:
	struct TNode{TNode* pNext;TNode* pPrev;TYPE data;};
	ULONG  m_nCount;
	HANDLE m_hHeapMem;
	TNode* m_pNodeHead;
	TNode* m_pNodeTail;
	TNode* m_pNodeFree;
	
protected:
	void _FreeNode(TNode* pNode);
	PNODE _NewNode(TNode* pPrev, TNode* pNext);

public:
	CXList();
	~CXList();
	BOOL Initialize(ULONG nInitSize = 10);
	void Uninitialize();

	ULONG GetCount();
	TYPE* GetHead();
	TYPE* GetTail();
	TYPE* GetAt(PNODE pNode);
	TYPE* GetNext(PNODE pNode);
	TYPE* GetPrev(PNODE pNode);
	TYPE* operator[](UINT nIndex);

	BOOL IsEmpty();
	void RemoveAt(PNODE pNode);
	void RemoveAll();
	void RemoveHead();
	void RemoveTail();

	PNODE AddHead(CXList* pNewList);
	PNODE AddTail(CXList* pNewList);
	PNODE AddHead(TYPE newElement);
	PNODE AddTail(TYPE newElement);

	BOOL SetAt(PNODE pNode, TYPE newElement);
	PNODE InsertBefore(PNODE pNode, TYPE newElement);
	PNODE InsertAfter(PNODE pNode, TYPE newElement);
	PNODE Find(TYPE searchValue, PNODE pNode=NULL);
	PNODE FindIndex(ULONG nIndex);
};

//-----------------------------------------------------------------------------
template<class TYPE>
CXList<TYPE>::CXList()
{
	
}

template<class TYPE>
CXList<TYPE>::~CXList()
{	
	
}

template<class TYPE>
inline void CXList<TYPE>::_FreeNode(TNode* pNode)
{
	m_nCount--;
	pNode->data.~TYPE();
	if (m_hHeapMem != INVALID_HANDLE_VALUE)
	{
		if (HeapFree(m_hHeapMem,0,pNode)==TRUE)
		{
			return;
		}
	}
	MessageBox(NULL,TEXT("_FreeNode failed!"),TEXT("Error"),MB_ICONERROR|MB_OK);
}

template<class TYPE>
inline PNODE CXList<TYPE>::_NewNode(TNode* pPrev, TNode* pNext)
{	
	if (m_hHeapMem==INVALID_HANDLE_VALUE)
	{
		m_hHeapMem = HeapCreate(NULL,1024,0);
		if (m_hHeapMem==INVALID_HANDLE_VALUE)
		{
			return NULL;
		}
	}

	TNode *pNode = (TNode*)HeapAlloc(m_hHeapMem,HEAP_ZERO_MEMORY,sizeof(TNode));
	if (pNode!=NULL)
	{	
		pNode->pPrev = pPrev;
		pNode->pNext = pNext;
		if (pPrev!=NULL)
		{
			pPrev->pNext = pNode;
		}
		if (pNext!=NULL)
		{
			pNext->pPrev = pNode;
		}
		m_nCount++;
	}
	return pNode;
}

template<class TYPE>
BOOL CXList<TYPE>::Initialize(ULONG nInitSize = 10)
{	
	m_nCount	 = 0;
	m_hHeapMem	 = INVALID_HANDLE_VALUE;
	m_pNodeHead	 = NULL;
	m_pNodeTail	 = NULL;
	m_pNodeFree	 = NULL;
	m_hHeapMem   = HeapCreate(NULL,nInitSize,0);
	if (m_hHeapMem==INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	return TRUE;
}

template<class TYPE>
void CXList<TYPE>::Uninitialize()
{
	RemoveAll();
}

template<class TYPE>
TYPE* CXList<TYPE>::operator[](UINT nIndex)
{
	TNode* pNode = (TNode*)FindIndex(nIndex);
	return &(pNode->data);
}

template<class TYPE>
inline ULONG CXList<TYPE>::GetCount()
{
	return m_nCount;
}

template<class TYPE>
inline TYPE* CXList<TYPE>::GetHead()
{
	return m_pNodeHead==NULL ? NULL : &(m_pNodeHead->data);
}

template<class TYPE>
inline TYPE* CXList<TYPE>::GetTail()
{
	return m_pNodeTail==NULL ? NULL : &(m_pNodeTail->data);
}

template<class TYPE>
inline TYPE* CXList<TYPE>::GetAt(PNODE pNode)
{
	TNode* pNODE = (TNode*)pNode;
	return pNODE==NULL ? NULL : &(pNODE->data);
}

template<class TYPE>
inline TYPE* CXList<TYPE>::GetNext(PNODE pNode)
{
	TNode* pNODE = (TNode*)pNode;
	if (pNODE != NULL)
	{
		pNODE = pNODE->pNext;
		return pNODE==NULL ? NULL : &(pNODE->data);
	}
	return NULL;
}

template<class TYPE>
inline TYPE* CXList<TYPE>::GetPrev(PNODE pNode)
{
	TNode* pNODE = (TNode*)pNode;
	if (pNODE != NULL)
	{
		pNODE = pNODE->pPrev;
		return pNODE==NULL ? NULL : &(pNODE->data);
	}
	return NULL;
}

template<class TYPE>
inline BOOL CXList<TYPE>::IsEmpty()
{
	return m_nCount==0 ? TRUE : FALSE;
}

template<class TYPE>
PNODE CXList<TYPE>::AddHead(CXList* pNewList)
{	
	if (pNewList!=NULL)
	{
		TNode* pNewNode = NULL;
		ULONG nCount = pNewList->GetCount();
		for (TNode* pIndex=pNewList->FindIndex(nCount-1); pIndex!=NULL; pIndex=pIndex->pPrev)
		{
			pNewNode = NULL;
			pNewNode = (TNode*)_NewNode(NULL, m_pNodeHead);
			if (pNewNode != NULL)
			{	
				pNewNode->data = pIndex->data;
				m_pNodeHead = pNewNode;
				if (m_pNodeTail==NULL)
				{
					m_pNodeTail = pNewNode;
				}
			}
		}
	}
	return m_pNodeHead;
}

template<class TYPE>
PNODE CXList<TYPE>::AddTail(CXList* pNewList)
{
	if (pNewList!=NULL)
	{	
		TNode* pNewNode = NULL;
		for (TNode* pIndex=pNewList->FindIndex(0); pIndex!=NULL; pIndex=pIndex->pPrev)
		{
			pNewNode = NULL;
			pNewNode = (TNode*)_NewNode(m_pNodeTail, NULL);
			if (pNewNode != NULL)
			{
				pNewNode->data = pIndex->data;
				m_pNodeTail = pNewNode;
				if (m_pNodeHead==NULL)
				{
					m_pNodeHead = pNewNode;
				}
			}
		}
	}
	return m_pNodeTail;
}

template<class TYPE>
PNODE CXList<TYPE>::AddHead(TYPE newElement)
{	
	TNode* pNewNode = (TNode*)_NewNode(NULL, m_pNodeHead);
	if (pNewNode != NULL)
	{
		pNewNode->data = newElement;
		m_pNodeHead = pNewNode;
		if (m_pNodeTail==NULL)
		{
			m_pNodeTail = pNewNode;
		}
	}
	return pNewNode;
}

template<class TYPE>
PNODE CXList<TYPE>::AddTail(TYPE newElement)
{
	TNode* pNewNode = (TNode*)_NewNode(m_pNodeTail, NULL);
	if (pNewNode != NULL)
	{
		pNewNode->data = newElement;
		m_pNodeTail = pNewNode;
		if (m_pNodeHead == NULL)
		{
			m_pNodeHead = pNewNode;
		}
	}
	return pNewNode;
}

template<class TYPE>
void CXList<TYPE>::RemoveAt(PNODE pNode)
{	
	if (pNode != NULL)
	{	
		TNode* pNODE = (TNode*)pNode;
		TNode* pPrev = pNODE->pPrev;
		TNode* pNext = pNODE->pNext;
		if (pNODE==m_pNodeHead)
		{
			m_pNodeHead = m_pNodeHead->pNext;
		}
		else
		{
			pPrev->pNext = pNext;
		}

		if (pNODE==m_pNodeTail)
		{
			m_pNodeTail = m_pNodeTail->pPrev;
		}
		else
		{
			pNext->pPrev = pPrev;
		}
		
		_FreeNode(pNODE);
	}
}

template<class TYPE>
void CXList<TYPE>::RemoveAll()
{	
	for (TNode* pIndex=m_pNodeHead; pIndex!=NULL; pIndex=pIndex->pNext)
	{
		pIndex->data.~TYPE();
	}
	
	if (m_hHeapMem != INVALID_HANDLE_VALUE)
	{
		if (HeapDestroy(m_hHeapMem)==TRUE)
		{
			m_nCount = 0;
			m_pNodeHead = NULL;
			m_pNodeTail = NULL;
			m_hHeapMem = INVALID_HANDLE_VALUE;
			return;
		}
	}

	MessageBox(NULL,TEXT("RemoveAll failed!"),TEXT("Error"),MB_ICONERROR|MB_OK);
}

template<class TYPE>
void CXList<TYPE>::RemoveHead()
{
	if (m_pNodeHead != NULL)
	{
		TNode *pNodeFree = m_pNodeHead;
		m_pNodeHead = m_pNodeHead->pNext;
		_FreeNode(pNodeFree);
	}
	else
	{
		m_pNodeTail = NULL;
	}
}

template<class TYPE>
void CXList<TYPE>::RemoveTail()
{
	if (m_pNodeTail != NULL)
	{
		TNode *pNodeFree = m_pNodeTail;
		m_pNodeTail = m_pNodeTail->pPrev;
		_FreeNode(pNodeFree);
	}
	else
	{
		m_pNodeHead = NULL;
	}
}

template<class TYPE>
BOOL CXList<TYPE>::SetAt(PNODE pNode, TYPE newElement)
{
	if (pNode != NULL)
	{	
		TNode* pNODE = (TNode*)pNode;
		pNODE->data = newElement;
		return TRUE;
	}
	return FALSE;
}

template<class TYPE>
PNODE CXList<TYPE>::InsertBefore(PNODE pNode, TYPE newElement)
{	
	if (pNode!=NULL)
	{	
		TNode* pNODE = (TNode*)pNode;
		TNode* pNew = _NewNode(pNODE->pPrev,pNODE);
		if (pNew != NULL)
		{	
			pNew->data = newElement;
			if (pNew->pPrev==NULL)
			{
				m_pNodeHead = pNew;
			}
			return pNew;
		}
	}
	return NULL;
}

template<class TYPE>
PNODE CXList<TYPE>::InsertAfter(PNODE pNode, TYPE newElement)
{
	if (pNode!=NULL)
	{	
		TNode* pNODE = (TNode*)pNode;
		TNode* pNew = _NewNode(pNODE,pNODE->pNext);
		if (pNew != NULL)
		{
			pNew->data = newElement;
			if (pNew->pNext==NULL)
			{
				m_pNodeTail = pNew;
			}
			return pNew;
		}
	}
	return NULL;
}

template<class TYPE>
inline PNODE CXList<TYPE>::Find(TYPE searchValue, PNODE pNode)
{
	for (TNode* pIndex=m_pNodeHead; pIndex!=NULL; pIndex=pIndex->pNext)
	{
		if (pIndex->data==searchValue)
		{
			return pIndex;
		}
	}
	return NULL;
}

template<class TYPE>
inline PNODE CXList<TYPE>::FindIndex(ULONG nIndex)
{	
	if (nIndex<0 || nIndex>m_nCount)
	{
		return NULL;
	}
	else
	{
		TNode* pIndex = m_pNodeHead;
		for (ULONG i=0; i<nIndex; i++)
		{
			if (pIndex != NULL)
			{
				pIndex = pIndex->pNext;
			}
		}
		return pIndex;
	}
}

ID870177103 2015-06-17
  • 打赏
  • 举报
回复
代码写的不错,但不接轨 C++11支持列表枚举for (It i : a) *i ;这样的写法 而你的代码得写成

TYPE i ;
if (a.gethead (i)) { //为什么gethead没有返回p,为了调用getnext还得调用一次find
  i ;
  PVOID p = a.find (i ,NULL) ; 
  while (a.getnext (p ,i) ) {
    i ;
  }
}
乱用引用也是蛋疼的地方,用指针啊 还是谦虚一点吧
mewiteor 2015-06-17
  • 打赏
  • 举报
回复
我猜stl中每种容器都有不同的迭代器是为了方便编译作类型检查,这样在编译时更容易发现bug(假如有的话).
huanglin03 2015-06-17
  • 打赏
  • 举报
回复
修改两处BUG
void CXList<TYPE>::RemoveAll()
{
	TNode *pNodeFree = NULL;
	for (TNode* pIndex=m_pNodeHead; pIndex!=NULL; _FreeNode(pNodeFree))
	{
		pNodeFree = pIndex;
		pIndex=pIndex->pNext;
	}
	m_nCount = 0; //这一句要加上
}

template<class TYPE>
void CXList<TYPE>::Uninitialize()
{
	RemoveAll();    //这一句要加上
	//添空堆内存
	if (m_hHeapMem != INVALID_HANDLE_VALUE)
	{
		HeapDestroy(m_hHeapMem);
		m_hHeapMem = INVALID_HANDLE_VALUE;
	}
}

还有两个函数 template<class TYPE> PVOID CXList<TYPE>::AddHead(CXList* pNewList) { return NULL; } template<class TYPE> PVOID CXList<TYPE>::AddTail(CXList* pNewList) { return NULL; } 马上就好
huanglin03 2015-06-17
  • 打赏
  • 举报
回复
可以把继承自CObject拿掉,这样想在哪用就在哪用,跨平台哟
huanglin03 2015-06-17
  • 打赏
  • 举报
回复
引用 3 楼 flyrack 的回复:
按你的逻辑所有的指针都不需要了 直接定义void* 用的时候自己转类型?
引用 1 楼 adlay 的回复:
void* 怎么可能代替STL的迭代器! 空结构体指针不晓得你说的是啥子
引用 5 楼 ID870177103 的回复:
不能代替的原因就是不够方便,void*不支持运算符重载(请忽视全局重载),每次使用都有类型转换,大工程的类名都很长,一转换显得代码很臃肿,空结构指针是什么鬼?
下面的代码是爷爷自己写的模板,看看用起来是不是更简单,拿去用吧,骚年们
#pragma once

//模板声明
template<class TYPE> 
class CXList : public CObject
{	
protected:
	struct TNode{TNode* pNext;TNode* pPrev;TYPE data;};
	ULONG  m_nCount;
	HANDLE m_hHeapMem;
	TNode* m_pNodeHead;
	TNode* m_pNodeTail;
	TNode* m_pNodeFree;
	
protected:
	void _FreeNode(TNode* pNode);
	PVOID _NewNode(TNode* pPrev, TNode* pNext);

public:
	CXList();
	~CXList();
	BOOL Initialize(ULONG nInitSize = 10);
	void Uninitialize();

	TYPE& operator[](UINT nIndex);

	ULONG GetCount();
	BOOL GetHead(TYPE& RetElement);
	BOOL GetTail(TYPE& RetElement);
	BOOL GetAt(PVOID pNode, TYPE& RetElement);
	BOOL GetNext(PVOID& pNode, TYPE& RetElement);
	BOOL GetPrev(PVOID& pNode, TYPE& RetElement);

	BOOL IsEmpty();
	void RemoveAt(PVOID pNode);
	void RemoveAll();
	void RemoveHead();
	void RemoveTail();

	PVOID AddHead(CXList* pNewList);
	PVOID AddTail(CXList* pNewList);
	PVOID AddHead(TYPE newElement);
	PVOID AddTail(TYPE newElement);

	BOOL SetAt(PVOID pNode, TYPE newElement);
	PVOID InsertBefore(PVOID pNode, TYPE newElement);
	PVOID InsertAfter(PVOID pNode, TYPE newElement);
	PVOID Find(TYPE searchValue, PVOID pNode=NULL);
	PVOID FindIndex(ULONG nIndex);
};

//模板实现-----------------------------------------------------------------------------
template<class TYPE>
CXList<TYPE>::CXList()
{
	
}

template<class TYPE>
CXList<TYPE>::~CXList()
{	
	
}

template<class TYPE>
inline void CXList<TYPE>::_FreeNode(TNode* pNode)
{
	m_nCount--;
	pNode->data.~TYPE();
	if (HeapFree(m_hHeapMem,0,pNode)==FALSE)
	{
		MessageBox(NULL,TEXT("HeapFree failed!"),TEXT("Error"),MB_ICONERROR)
	}
}

template<class TYPE>
inline PVOID CXList<TYPE>::_NewNode(TNode* pPrev, TNode* pNext)
{	
	TNode *pNode = (TNode*)HeapAlloc(m_hHeapMem,HEAP_ZERO_MEMORY,sizeof(TNode));
	if (pNode!=NULL)
	{	
		pNode->pPrev = pPrev;
		pNode->pNext = pNext;
		if (pPrev!=NULL)
		{
			pPrev->pNext = pNode;
		}
		if (pNext!=NULL)
		{
			pNext->pPrev = pNode;
		}
		m_nCount++;
	}
	return pNode;
}

template<class TYPE>
BOOL CXList<TYPE>::Initialize(ULONG nInitSize = 10)
{
	m_nCount	 = 0;
	m_hHeapMem	 = INVALID_HANDLE_VALUE;
	m_pNodeHead	 = NULL;
	m_pNodeTail	 = NULL;
	m_pNodeFree	 = NULL;
	m_hHeapMem   = HeapCreate(NULL,nInitSize,0);
	if (m_hHeapMem==INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	return TRUE;
}

template<class TYPE>
void CXList<TYPE>::Uninitialize()
{
	//释放和清空
	m_nCount = 0;

	//添空堆内存
	if (m_hHeapMem != INVALID_HANDLE_VALUE)
	{
		HeapDestroy(m_hHeapMem);
		m_hHeapMem = INVALID_HANDLE_VALUE;
	}
}

template<class TYPE>
TYPE& CXList<TYPE>::operator[](UINT nIndex)
{
	TNode* pNode = (TNode*)FindIndex(nIndex);
	return pNode->data;
}

template<class TYPE>
inline ULONG CXList<TYPE>::GetCount()
{
	return m_nCount;
}

template<class TYPE>
inline BOOL CXList<TYPE>::GetHead(TYPE& RetElement)
{
	if (m_pNodeHead != NULL)
	{
		RetElement = m_pNodeHead->data;
		return TRUE;
	}
	return FALSE;
}

template<class TYPE>
inline BOOL CXList<TYPE>::GetTail(TYPE& RetElement)
{
	if (m_pNodeTail != NULL)
	{
		RetElement = m_pNodeTail->data;
		return TRUE;
	}
	return FALSE;
}

template<class TYPE>
inline BOOL CXList<TYPE>::GetAt(PVOID pNode, TYPE& RetElement)
{
	if (pNode != NULL)
	{
		TNode* pNODE = (TNode*)pNode;
		RetElement = pNODE->data;
		return TRUE;
	}
	return FALSE;
}

template<class TYPE>
inline BOOL CXList<TYPE>::GetNext(PVOID& pNode, TYPE& RetElement)
{
	if (pNode != NULL)
	{
		TNode* pNODE = (TNode*)pNode;
		pNODE = pNODE->pNext;
		if (pNODE != NULL)
		{
			RetElement = pNODE->data;
			return TRUE;
		}
	}
	return FALSE;
}

template<class TYPE>
inline BOOL CXList<TYPE>::GetPrev(PVOID& pNode, TYPE& RetElement)
{
	if (pNode != NULL)
	{
		TNode* pNODE = (TNode*)pNode;
		pNODE = pNODE->pPrev;
		if (pNODE != NULL)
		{
			RetElement = pNODE->data;
			return TRUE;
		}
	}
	return FALSE;
}

template<class TYPE>
inline BOOL CXList<TYPE>::IsEmpty()
{
	return m_nCount==0 ? TRUE : FALSE;
}

template<class TYPE>
PVOID CXList<TYPE>::AddHead(CXList* pNewList)
{
	return NULL;
}

template<class TYPE>
PVOID CXList<TYPE>::AddTail(CXList* pNewList)
{
	return NULL;
}

template<class TYPE>
PVOID CXList<TYPE>::AddHead(TYPE newElement)
{	
	TNode* pNewNode = (TNode*)_NewNode(NULL, m_pNodeHead);
	if (pNewNode != NULL)
	{
		pNewNode->data = newElement;
		if (m_pNodeHead != NULL)
		{
			m_pNodeHead->pPrev = pNewNode;
		}
		else
		{
			m_pNodeTail = pNewNode;
		}
		m_pNodeHead = pNewNode;
	}
	return pNewNode;
}

template<class TYPE>
PVOID CXList<TYPE>::AddTail(TYPE newElement)
{
	TNode* pNewNode = (TNode*)_NewNode(m_pNodeTail, NULL);
	if (pNewNode != NULL)
	{
		pNewNode->data = newElement;
		if (m_pNodeTail != NULL)
		{
			m_pNodeTail->pNext = pNewNode;
		}
		else
		{
			m_pNodeHead = pNewNode;
		}
		m_pNodeTail = pNewNode;
	}
	return pNewNode;
}

template<class TYPE>
void CXList<TYPE>::RemoveAt(PVOID pNode)
{	
	if (pNode != NULL)
	{	
		TNode* pNODE = (TNode*)pNode;
		TNode* pPrev = pNODE->pPrev;
		TNode* pNext = pNODE->pNext;
		if (pNODE==m_pNodeHead)
		{
			m_pNodeHead = m_pNodeHead->pNext;
		}
		else if (pNODE==m_pNodeTail)
		{
			m_pNodeTail = m_pNodeTail->pPrev;
		}
		else
		{
			if (pPrev!=NULL)
			{
				pPrev->pNext = pNext;
			}
			if (pNext!=NULL)
			{
				pNext->pPrev = pPrev;
			}
		}
		_FreeNode(pNODE);
	}
}

template<class TYPE>
void CXList<TYPE>::RemoveAll()
{
	TNode *pNodeFree = NULL;
	for (TNode* pIndex=m_pNodeHead; pIndex!=NULL; _FreeNode(pNodeFree))
	{
		pNodeFree = pIndex;
		pIndex=pIndex->pNext;
	}
}

template<class TYPE>
void CXList<TYPE>::RemoveHead()
{
	TNode *pNodeFree = m_pNodeHead;
	if (m_pNodeHead != NULL)
	{
		m_pNodeHead = m_pNodeHead->pNext;
		_FreeNode(pNodeFree);
	}
}

template<class TYPE>
void CXList<TYPE>::RemoveTail()
{
	TNode *pNodeFree = m_pNodeTail;
	if (m_pNodeTail != NULL)
	{
		m_pNodeTail = m_pNodeTail->pPrev;
		_FreeNode(pNodeFree);
	}
}

template<class TYPE>
BOOL CXList<TYPE>::SetAt(PVOID pNode, TYPE newElement)
{
	if (pNode != NULL)
	{
		TNode* pNODE = (TNode*)pNode;
		pNODE->data = newElement;
		return TRUE;
	}
	return FALSE;
}

template<class TYPE>
PVOID CXList<TYPE>::InsertBefore(PVOID pNode, TYPE newElement)
{	
	if (pNode!=NULL)
	{	
		TNode* pNODE = (TNode*)pNode;
		TNode* pNew = _NewNode(pNODE->pPrev,pNODE);
		if (pNew != NULL)
		{
			pNew->data = newElement;
			if (pNew->pPrev==NULL)
			{
				m_pNodeHead = pNew;
			}
			return pNew;
		}
	}
	return NULL;
}

template<class TYPE>
PVOID CXList<TYPE>::InsertAfter(PVOID pNode, TYPE newElement)
{
	if (pNode!=NULL)
	{	
		TNode* pNODE = (TNode*)pNode;
		TNode* pNew = _NewNode(pNODE,pNODE->pNext);
		if (pNew != NULL)
		{
			pNew->data = newElement;
			if (pNew->pNext==NULL)
			{
				m_pNodeTail = pNew;
			}
			return pNew;
		}
	}
	return NULL;
}

template<class TYPE>
inline PVOID CXList<TYPE>::Find(TYPE searchValue, PVOID pNode)
{
	for (TNode* pIndex=m_pNodeHead; pIndex!=NULL; pIndex=pIndex->pNext)
	{
		if (pIndex->data==searchValue)
		{
			return pIndex;
		}
	}
	return NULL;
}

template<class TYPE>
inline PVOID CXList<TYPE>::FindIndex(ULONG nIndex)
{	
	if (nIndex<0 || nIndex>m_nCount)
	{
		return NULL;
	}
	else
	{
		TNode* pIndex = m_pNodeHead;
		for (ULONG i=0; i<nIndex; i++)
		{
			if (pIndex != NULL)
			{
				pIndex = pIndex->pNext;
			}
		}
		return pIndex;
	}
}

ID870177103 2015-06-17
  • 打赏
  • 举报
回复
typedef unsigned long INDEX ;
#define INVALID_INDEX_VALUE ((INDEX) -1)

#if _MSC_VER == 1200
#define override
#endif

template <typename T>
class It {
public :
	class Itable {
	public :
		virtual const INDEX first () const = 0 ;
		virtual const INDEX last () const = 0 ;
		virtual const INDEX next (INDEX i) const = 0 ;
		virtual const INDEX prev (INDEX i) const = 0 ;
		virtual const bool contain (INDEX i) const = 0 ;
		virtual T &get (INDEX i) = 0 ;

		inline const It begin () {return It (*this ,first ()) ;}
		inline const It end () {return It (*this ,last ()) ;}

		inline T &operator[] (INDEX i) {return get (i) ;}
	} ;

private :
	Itable &ita ;
	INDEX i ;

public :
	inline It (Itable &ita ,INDEX i) :ita (ita) ,i (i) {}

	inline operator const bool () const {return ita.contain (i) ;}

	inline const It operator++ (int) {
		INDEX tmp = i ;
		i = ita.next (i) ;
		return It (ita ,tmp) ;
	}

	inline const It operator-- (int) {
		INDEX tmp = i ;
		i = ita.prev (i) ;
		return It (ita ,tmp) ;
	}

	inline T &operator* () {return ita.get (i) ;}

	inline T *const operator-> () {return &ita.get (i) ;}
} ;


template <typename T ,int S>
class List :public It<T>::Itable {
private :
	T buf[S] ;

public :
	const INDEX first () override const {return 0 ;}

	const INDEX last () override const {return S - 1 ;}

	const INDEX next (INDEX i) override const {return i + 1 ;}

	const INDEX prev (INDEX i) override const {return i - 1 ;}

	const bool contain (INDEX i) override const {return i >= 0 && i < S ;}

	T &get (INDEX i) override {return buf[i] ;}
} ;

#include <iostream>
using namespace std ;
#include <stdlib.h>
#include <time.h>

int main () {
	List<int ,256> l ;
	srand ((unsigned int) time (0)) ;
	for (int i = 0 ; i < 256 ; i++)
		cout << (l[i] = rand () % 10) << " " ;
	cout << endl ;

	int ct6 = 0 ;
	for (It<int> it = l.begin () ; it ; it++)
		if (*it == 6)
			ct6++ ;
	cout << ct6 << endl ;
	//其实迭代器跟你的代码差不多,只是重载之后写起来比较短
	//这里可以比较一下
	int ct5 = 0 ;
	for (INDEX idx = l.first () ; l.contain (idx) ; idx = l.next (idx))
		if (l.get (idx) == 5)
			ct5++ ;
	cout << ct5 << endl ;
	return 0 ;
}
huanglin03 2015-06-17
  • 打赏
  • 举报
回复
修改了一点代码, //-------------------------------------------------------------------------------------------------------------------------------- #pragma once typedef void* PNODE; template<class TYPE> class CXList { protected: struct TNode{TNode* pNext;TNode* pPrev;TYPE data;}; ULONG m_nCount; HANDLE m_hHeapMem; TNode* m_pNodeHead; TNode* m_pNodeTail; protected: void _FreeNode(TNode* pNode); PNODE _NewNode(TNode* pPrev, TNode* pNext); public: CXList(); ~CXList(); BOOL Initialize(ULONG nInitSize = 10); void Uninitialize(); ULONG GetCount(); TYPE* GetHead(); TYPE* GetTail(); TYPE* GetAt(PNODE pNode); TYPE* GetNext(PNODE pNode); TYPE* GetPrev(PNODE pNode); TYPE* operator[](UINT nIndex); BOOL IsEmpty(); void RemoveAt(PNODE pNode); void RemoveAll(); void RemoveHead(); void RemoveTail(); PNODE AddHead(CXList* pNewList); PNODE AddTail(CXList* pNewList); PNODE AddHead(TYPE newElement); PNODE AddTail(TYPE newElement); BOOL SetAt(PNODE pNode, TYPE newElement); PNODE InsertBefore(PNODE pNode, TYPE newElement); PNODE InsertAfter(PNODE pNode, TYPE newElement); PNODE Find(TYPE searchValue, PNODE pNode=NULL); PNODE FindIndex(ULONG nIndex); }; //--------------------------------------------------------------------------------------------------------------- template<class TYPE> CXList<TYPE>::CXList() { } template<class TYPE> CXList<TYPE>::~CXList() { } template<class TYPE> inline void CXList<TYPE>::_FreeNode(TNode* pNode) { pNode->data.~TYPE(); if (m_hHeapMem != INVALID_HANDLE_VALUE) { if (HeapFree(m_hHeapMem,0,pNode)==TRUE) { m_nCount--; m_nCount = min(m_nCount,0); return; } } MessageBox(NULL,TEXT("_FreeNode failed!"),TEXT("Error"),MB_ICONERROR|MB_OK); } template<class TYPE> inline PNODE CXList<TYPE>::_NewNode(TNode* pPrev, TNode* pNext) { if (m_hHeapMem==INVALID_HANDLE_VALUE) { m_hHeapMem = HeapCreate(NULL,1024,0); if (m_hHeapMem==INVALID_HANDLE_VALUE) { return NULL; } } TNode *pNode = (TNode*)HeapAlloc(m_hHeapMem,HEAP_ZERO_MEMORY,sizeof(TNode)); if (pNode!=NULL) { pNode->pPrev = pPrev; pNode->pNext = pNext; if (pPrev!=NULL) { pPrev->pNext = pNode; } if (pNext!=NULL) { pNext->pPrev = pNode; } m_nCount++; } return pNode; } template<class TYPE> BOOL CXList<TYPE>::Initialize(ULONG nInitSize = 10) { m_nCount = 0; m_hHeapMem = INVALID_HANDLE_VALUE; m_pNodeHead = NULL; m_pNodeTail = NULL; m_hHeapMem = HeapCreate(NULL,nInitSize,0); if (m_hHeapMem==INVALID_HANDLE_VALUE) { return FALSE; } return TRUE; } template<class TYPE> void CXList<TYPE>::Uninitialize() { RemoveAll(); } template<class TYPE> inline ULONG CXList<TYPE>::GetCount() { return m_nCount; } template<class TYPE> inline TYPE* CXList<TYPE>::GetHead() { return m_pNodeHead==NULL ? NULL : &(m_pNodeHead->data); } template<class TYPE> inline TYPE* CXList<TYPE>::GetTail() { return m_pNodeTail==NULL ? NULL : &(m_pNodeTail->data); } template<class TYPE> inline TYPE* CXList<TYPE>::GetAt(PNODE pNode) { TNode* pNODE = (TNode*)pNode; return pNODE==NULL ? NULL : &(pNODE->data); } template<class TYPE> inline TYPE* CXList<TYPE>::GetNext(PNODE pNode) { TNode* pNODE = (TNode*)pNode; if (pNODE != NULL) { pNODE = pNODE->pNext; return pNODE==NULL ? NULL : &(pNODE->data); } return NULL; } template<class TYPE> inline TYPE* CXList<TYPE>::GetPrev(PNODE pNode) { TNode* pNODE = (TNode*)pNode; if (pNODE != NULL) { pNODE = pNODE->pPrev; return pNODE==NULL ? NULL : &(pNODE->data); } return NULL; } template<class TYPE> TYPE* CXList<TYPE>::operator[](UINT nIndex) { TNode* pNode = (TNode*)FindIndex(nIndex); return pNode==NULL ? NULL : &(pNode->data); } template<class TYPE> inline BOOL CXList<TYPE>::IsEmpty() { return m_nCount==0 ? TRUE : FALSE; } template<class TYPE> PNODE CXList<TYPE>::AddHead(CXList* pNewList) { if (pNewList!=NULL) { TNode* pNewNode = NULL; ULONG nCount = pNewList->GetCount(); for (TNode* pIndex=pNewList->FindIndex(nCount-1); pIndex!=NULL; pIndex=pIndex->pPrev) { pNewNode = NULL; pNewNode = (TNode*)_NewNode(NULL, m_pNodeHead); if (pNewNode != NULL) { pNewNode->data = pIndex->data; m_pNodeHead = pNewNode; if (m_pNodeTail==NULL) { m_pNodeTail = pNewNode; } } } } return m_pNodeHead; } template<class TYPE> PNODE CXList<TYPE>::AddTail(CXList* pNewList) { if (pNewList!=NULL) { TNode* pNewNode = NULL; for (TNode* pIndex=pNewList->FindIndex(0); pIndex!=NULL; pIndex=pIndex->pPrev) { pNewNode = NULL; pNewNode = (TNode*)_NewNode(m_pNodeTail, NULL); if (pNewNode != NULL) { pNewNode->data = pIndex->data; m_pNodeTail = pNewNode; if (m_pNodeHead==NULL) { m_pNodeHead = pNewNode; } } } } return m_pNodeTail; } template<class TYPE> PNODE CXList<TYPE>::AddHead(TYPE newElement) { TNode* pNewNode = (TNode*)_NewNode(NULL, m_pNodeHead); if (pNewNode != NULL) { pNewNode->data = newElement; m_pNodeHead = pNewNode; if (m_pNodeTail==NULL) { m_pNodeTail = pNewNode; } } return pNewNode; } template<class TYPE> PNODE CXList<TYPE>::AddTail(TYPE newElement) { TNode* pNewNode = (TNode*)_NewNode(m_pNodeTail, NULL); if (pNewNode != NULL) { pNewNode->data = newElement; m_pNodeTail = pNewNode; if (m_pNodeHead == NULL) { m_pNodeHead = pNewNode; } } return pNewNode; } template<class TYPE> void CXList<TYPE>::RemoveAt(PNODE pNode) { if (pNode != NULL) { TNode* pNODE = (TNode*)pNode; TNode* pPrev = pNODE->pPrev; TNode* pNext = pNODE->pNext; if (m_pNodeHead==pNODE) { m_pNodeHead = m_pNodeHead->pNext; } else { pPrev->pNext = pNext; } if (m_pNodeTail==pNODE) { m_pNodeTail = m_pNodeTail->pPrev; } else { pNext->pPrev = pPrev; } _FreeNode(pNODE); } } template<class TYPE> void CXList<TYPE>::RemoveAll() { for (TNode* pIndex=m_pNodeHead; pIndex!=NULL; pIndex=pIndex->pNext) { pIndex->data.~TYPE(); } if (m_hHeapMem != INVALID_HANDLE_VALUE) { if (HeapDestroy(m_hHeapMem)==TRUE) { m_nCount = 0; m_pNodeHead = NULL; m_pNodeTail = NULL; m_hHeapMem = INVALID_HANDLE_VALUE; return; } } MessageBox(NULL,TEXT("RemoveAll failed!"),TEXT("Error"),MB_ICONERROR|MB_OK); } template<class TYPE> void CXList<TYPE>::RemoveHead() { if (m_pNodeHead != NULL) { TNode *pNodeFree = m_pNodeHead; m_pNodeHead = m_pNodeHead->pNext; if (m_pNodeHead==NULL) { m_pNodeTail = NULL; } _FreeNode(pNodeFree); } } template<class TYPE> void CXList<TYPE>::RemoveTail() { if (m_pNodeTail != NULL) { TNode *pNodeFree = m_pNodeTail; m_pNodeTail = m_pNodeTail->pPrev; if (m_pNodeTail==NULL) { m_pNodeHead = NULL; } _FreeNode(pNodeFree); } } template<class TYPE> BOOL CXList<TYPE>::SetAt(PNODE pNode, TYPE newElement) { if (pNode != NULL) { TNode* pNODE = (TNode*)pNode; pNODE->data = newElement; return TRUE; } return FALSE; } template<class TYPE> PNODE CXList<TYPE>::InsertBefore(PNODE pNode, TYPE newElement) { if (pNode!=NULL) { TNode* pNODE = (TNode*)pNode; TNode* pNew = _NewNode(pNODE->pPrev,pNODE); if (pNew != NULL) { pNew->data = newElement; if (pNew->pPrev==NULL) { m_pNodeHead = pNew; } return pNew; } } return NULL; } template<class TYPE> PNODE CXList<TYPE>::InsertAfter(PNODE pNode, TYPE newElement) { if (pNode!=NULL) { TNode* pNODE = (TNode*)pNode; TNode* pNew = _NewNode(pNODE,pNODE->pNext); if (pNew != NULL) { pNew->data = newElement; if (pNew->pNext==NULL) { m_pNodeTail = pNew; } return pNew; } } return NULL; } template<class TYPE> inline PNODE CXList<TYPE>::Find(TYPE searchValue, PNODE pNode) { for (TNode* pIndex=m_pNodeHead; pIndex!=NULL; pIndex=pIndex->pNext) { if (pIndex->data==searchValue) { return pIndex; } } return NULL; } template<class TYPE> inline PNODE CXList<TYPE>::FindIndex(ULONG nIndex) { if (nIndex>=0 && nIndex<m_nCount) { TNode* pIndex = m_pNodeHead; for (UINT i=0; i<nIndex && pIndex!=NULL; i++) { pIndex = pIndex->pNext; } return pIndex; } return NULL; }
huanglin03 2015-06-17
  • 打赏
  • 举报
回复
引用 15 楼 adlay 的回复:
[quote=引用 8 楼 bug1190 的回复:] 修改两处BUG 马上就好
迭代器的设计思想是模拟原始类型的迭代操作,这样算法可以统一设计,比如

int a[] = { 1, 2, 3, 4, 5 };
std::find(a, a + 5, 3);
 
std::vector<int> b(5, 3);
std::find(b.begin(), b.end(), 3);
std::find 能够同时对原始数组和STL容器进行操作,都是靠迭代器的设计模拟了原始指针的行为。 而你的代码只不过是提供了一个遍历的方法而已,根本没做到迭代器所完成的功能,没办法在这基础上设计统一的算法[/quote] 写个简洁的模板给你用就行了,要是能写一套能操作各种数据结构(数组、队列、链表、树、双向队列、双向链表、二叉树,循环队列等)的标准的增,删,查,改的操作方法,那是需要先想好架构的,我只保证,我写的代码,比你用的STL的的库里的LIST和MFC中的LIST,第一简洁,第二效率高,这就够了
ID870177103 2015-06-16
  • 打赏
  • 举报
回复
不能代替的原因就是不够方便,void*不支持运算符重载(请忽视全局重载),每次使用都有类型转换,大工程的类名都很长,一转换显得代码很臃肿,空结构指针是什么鬼?
huanglin03 2015-06-16
  • 打赏
  • 举报
回复
引用 3 楼 flyrack 的回复:
按你的逻辑所有的指针都不需要了 直接定义void* 用的时候自己转类型?
等明天贴代码给你们看,一边玩泥巴去,
flyrack 2015-06-16
  • 打赏
  • 举报
回复
按你的逻辑所有的指针都不需要了 直接定义void* 用的时候自己转类型?
huanglin03 2015-06-16
  • 打赏
  • 举报
回复
引用 1 楼 adlay 的回复:
void* 怎么可能代替STL的迭代器! 空结构体指针不晓得你说的是啥子
等爷爷写出来了你就明白爷爷说的是啥了
www_adintr_com 2015-06-16
  • 打赏
  • 举报
回复
void* 怎么可能代替STL的迭代器! 空结构体指针不晓得你说的是啥子

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧