利用CPtrList管理一堆对象,现在需要遍历链表,删除其中符合要求的结点,代码如下:POSITION pos = m_accountlist.GetHeadPosition();
for(int i = 0; i<m_accountlist.GetCount();i++)
{
CAccount* pAccount = (CAccount*)m_accountlist.GetNext(pos);
if(pAccount->m_name == "abc")
{
m_accountlist.GetPrev(pos);
m_accountlist.RemoveAt(pos);
return;
}
}说明一下:m_accountlist是CPtrList类型的链表,里面都是CAccount类型的指针。现在遍历链表,查找m_name 为 "abc"的元素并删除。由于GetNext(pos)函数会使pos移到下一个元素的位置,所以我先调用GetPrev(pos)使pos回到刚才找到的正确位置上,然后在调用RemoveAt进行删除。对于多个元素时开始是正确的,但当链表只有一个元素时,GetPrev(pos)就会报错,因为此时的pos是一个无效的位置。如果不加m_accountlist.GetPrev(pos);则删除的元素是要删除元素的下一个元素,就不对了。请问应该如何处理呢?

解决方案 »

  1.   

    for(int i = m_accountlist.GetCount()-1; i>=0;--i)
    {
    CAccount* pAccount = (CAccount*)m_accountlist.GetAt(i);
    if(pAccount->m_name == "abc")
    {
    m_accountlist.RemoveAt(i);
    delete pAccount;
    return;
    }
    }
      

  2.   

    p = m_accountlist.GetPrev(pos);
    判断一下元素是否为空
      

  3.   

    我用你的代码试了下,报错,说GetAt函数和RemoveAt函数只能用POSITION类型的参数,不能用int类型error C2664: 'RemoveAt' : cannot convert parameter 1 from 'int' to 'struct __POSITION *' Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
      

  4.   

    不是判断是否为空的问题,即使加了也会出错,因为只有一个元素时,此时的pos已经是一个无效的位置了,所以GetPrev(pos)这个调用就会异常。
      

  5.   


    // 这样试一下,随手写的,没有测试
    POSITION pos = m_accountlist.GetTailPosition();
    while(pos)
    {
    CAccount* pAccount = (CAccount*)m_accountlist.GetAt(pos);
    if(pAccount->n_name == "abc")
    {
    m_accountlist.RemoveAt(pos);
    }
    m_accountlist.GetPrev(pos);
    }
      

  6.   

    我试了下VisualEleven大侠的代码,调试中发现会出现这样的情况:在链表中只添加一个元素:如abc,执行完m_accountlist.RemoveAt(pos);之后,链表为空,然后执行m_accountlist.GetPrev(pos);后pos不为0,故后面会出错。如果在链表中添加两个或以上元素,如abc,aaa,abc,则两个abc都会被删除,最后一次执行 m_accountlist.GetPrev(pos);后pos为0,可以正确退出循环。真的很奇怪!请各位大侠指点!
      

  7.   

    我在VisualEleven大侠的代码中加了一句:POSITION pos = m_accountlist.GetTailPosition();
        while(pos)
        {        
            CAccount* pAccount = (CAccount*)m_accountlist.GetAt(pos);
            if(pAccount->n_name == "abc")
            {
                m_accountlist.RemoveAt(pos);
            }
            if(m_accountlist.GetCount() == 0)
    {
        break;
    }
            m_accountlist.GetPrev(pos);
        }好像基本就没问题了,不知是否可取?