随笔 - 493  文章 - 0  评论 - 97  阅读 - 239万

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;
}
posted on   清清飞扬  阅读(7129)  评论(4编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
< 2010年11月 >
31 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 1 2 3 4
5 6 7 8 9 10 11

点击右上角即可分享
微信分享提示