CPtrList操作--插入,删除特定元素,删除全部

新建一个基于对话框的MFC应用程序,界面如下(属性等全采用默认):

首先,添加一个简单的结构体定义(可选择在对话框类定义的前面):

typedef struct _tagNode
{
	CString name;
	int age;
}Node;

 再为对话框类添加一个成员变量:

private:

         CPtrList m_list;

接着为对话框类添加几个成员函数:

void CDxDlg::InsertNode(UINT n)		// 插入n个元素	
{
	for(UINT i = 0; i < n; i++)
	{
		Node * pNode = new Node;
		pNode->name.Format("name%d", i+1);
		pNode->age = 10 * (i+1);

		m_list.AddTail(pNode);
	}
}

void CDxDlg::Display()				// 显示列表中的元素
{
	POSITION pos;
	CString info;
	for(pos = m_list.GetHeadPosition(); pos != NULL;)
	{
		Node *pNode = (Node*)m_list.GetNext(pos);
		if(pNode != NULL)
		{
			info.Format("name = %s, age = %d", pNode->name, pNode->age);
			MessageBox(info);
		}
	}
}

BOOL CDxDlg::RemoveNode(Node *pNode)		// 根据特定结点
{
	if(pNode)
	{
		POSITION pos, temp;
		for(pos = m_list.GetHeadPosition(); pos != NULL; )
		{
			temp = pos;
			Node *node = (Node *) m_list.GetNext(pos);
			if(node && node->name == pNode->name)	// 删除第一个姓名相同的元素
			{
				delete node;				// 删除前应该释放分配的空间
				m_list.RemoveAt(temp);		// 删除元素
				return TRUE;
			}
		}
	}
	return FALSE;							// 删除失败(找不到符合删除条件的元素)
}

在对话框的OnInitDialog()中调用插入结点函数,如 InsertNode(5);

为按钮1添加点击事件:

void CDxDlg::OnButton1()			// 从列表中删除与编辑框中输入姓名相同的结点
{
	CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
	CString delName;				// 将要被删除结点的姓名(name)
	pEdit->GetWindowText(delName);

	Node node;
	node.name = delName;
	node.age = 0;

	if(RemoveNode(&node))			// 删除结点
	{
		MessageBox("Remove node succ");
	}
	else
	{
		MessageBox("Remove node failed");
	}
	Display();						// 不管删除成功与否,显示操作后列表中的元素
}

另外要注意的就是在关闭对话框的时候,要释放所分配的空间,所以添加了对话框的DestroyWindow(),代码如下:

BOOL CDxDlg::DestroyWindow()
{
	POSITION pos, temp;
	for(pos = m_list.GetHeadPosition(); pos; )
	{
		temp = pos;
		Node * node = (Node*) m_list.GetNext(pos);
		if(node)
		{
			delete node;					// 释放空间
			m_list.RemoveAt(temp);			// 删除元素
		}
	}
	return CDialog::DestroyWindow();
}

 释放CPtrList队列中的元素可以使用下面的函数:

/*
	功能: 释放指定队列中的元素及队列本身(要求pList中的元素类型为: CMessBuf)
	@pList: 要释放的CMessBuf类队列
	@bDeleteObject: 是否释放pList指向的空间(默认值为TRUE,如果pList指向的空间不是用new分配的,在调用时可将此值设为FALSE)
*/
void CGateView::FreeList(CPtrList *pList, BOOL bDeleteObject)
{
	while(pList->GetCount() > 0)
	{
		Node *p = (Node*) pList->RemoveHead();
		if(p)
			delete p;
	}
	if(bDeleteObject && pList)
		delete pList;
}

原文地址:https://www.cnblogs.com/joeblackzqq/p/1879945.html