代码之家  ›  专栏  ›  技术社区  ›  Scott Langham

catllist::removeat是否使现有位置无效?

  •  1
  • Scott Langham  · 技术社区  · 15 年前

    我在看这个,M ou Rows是一个Catllist:

    void CData::RemoveAll()
    {
        size_t cItems = m_Rows.GetCount();
        POSITION Pos = m_Rows.GetHeadPosition();
    
        while(Pos != 0)
        {
            CItem* pItem = m_Rows.GetAt(Pos);
    
            if (pItem != 0)
                delete pItem;
    
            POSITION RemoveablePos = Pos;
            pItem = m_Rows.GetNext(Pos);
    
            m_Rows.RemoveAt(RemoveablePos);
        }
    }
    

    我想知道是否有可能removeat调用会使pos失效?

    1 回复  |  直到 15 年前
        1
  •  1
  •   Sebastian    15 年前

    根据 documentation ,catllist的行为类似于双链接列表,因此删除一个列表项 应该 不会使指向其他项的指针无效。这个 POSITION 类型直接引用列表项的内存位置:

    大多数catllist方法都使用位置值。这些方法使用该值来引用存储元素的实际内存位置,不应直接计算或预测该值。

    在Atlcoll.h中似乎不是这样的:

    template< typename E, class ETraits >
    void CAtlList< E, ETraits >::RemoveAt( POSITION pos )
    {
    ATLASSERT_VALID(this);
    ATLENSURE( pos != NULL );
    
    CNode* pOldNode = (CNode*)pos;
    
    // remove pOldNode from list
    if( pOldNode == m_pHead )
    {
        m_pHead = pOldNode->m_pNext;
    }
    else
    {
        ATLASSERT( AtlIsValidAddress( pOldNode->m_pPrev, sizeof(CNode) ));
        pOldNode->m_pPrev->m_pNext = pOldNode->m_pNext;
    }
    if( pOldNode == m_pTail )
    {
        m_pTail = pOldNode->m_pPrev;
    }
    else
    {
        ATLASSERT( AtlIsValidAddress( pOldNode->m_pNext, sizeof(CNode) ));
        pOldNode->m_pNext->m_pPrev = pOldNode->m_pPrev;
    }
    FreeNode( pOldNode );
    }