最简单链表实现

下面由MFC代码中抽取来,以最简便的方式实现了的链表功能:

#include <windows.h>
#include <stddef.h>
#include <stdio.h>

#define AFX_INLINE inline /*__forceinline*/
#define ASSERT(f)          ((void)0)
#define AFX_NOVTABLE
#define DEBUG_ONLY(f)      (f)

class CSimpleList
{
public:
    CSimpleList(int nNextOffset = 0);
    void Construct(int nNextOffset);
    
    // Operations
    BOOL IsEmpty() const;
    void AddHead(void* p);
    void RemoveAll();
    void* GetHead() const;
    void* GetNext(void* p) const;
    BOOL Remove(void* p);
    
    // Implementation
    void* m_pHead;
    size_t m_nNextOffset;
    
    void** GetNextPtr(void* p) const;   // somewhat trusting...
};

AFX_INLINE CSimpleList::CSimpleList(int nNextOffset)
{
    m_pHead = NULL; 
    m_nNextOffset = nNextOffset; 
}

AFX_INLINE void CSimpleList::Construct(int nNextOffset)
{ 
    ASSERT(m_pHead == NULL); 
    m_nNextOffset = nNextOffset; 
}

AFX_INLINE BOOL CSimpleList::IsEmpty() const
{
    return m_pHead == NULL; 
}

void CSimpleList::AddHead(void* p)
{
    ASSERT(p != NULL);
    ASSERT(*GetNextPtr(p) == NULL);
    
    *GetNextPtr(p) = m_pHead;
    m_pHead = p;
}

AFX_INLINE void** CSimpleList::GetNextPtr(void* p) const
{ 
    ASSERT(p != NULL); 
    return (void**)((BYTE*)p+m_nNextOffset); 
}

AFX_INLINE void CSimpleList::RemoveAll()
{
    m_pHead = NULL; 
}

AFX_INLINE void* CSimpleList::GetHead() const
{
    return m_pHead; 
}

AFX_INLINE void* CSimpleList::GetNext(void* prevElement) const
{
    return *GetNextPtr(prevElement); 
}

BOOL CSimpleList::Remove(void* p)
{
    ASSERT(p != NULL);
    
    if (m_pHead == NULL)
        return FALSE;
    
    BOOL bResult = FALSE;
    if (m_pHead == p)
    {
        m_pHead = *GetNextPtr(p);
        DEBUG_ONLY(*GetNextPtr(p) = NULL);
        bResult = TRUE;
    }
    else
    {
        void* pTest = m_pHead;
        while (pTest != NULL && *GetNextPtr(pTest) != p)
            pTest = *GetNextPtr(pTest);
        if (pTest != NULL)
        {
            *GetNextPtr(pTest) = *GetNextPtr(p);
            DEBUG_ONLY(*GetNextPtr(p) = NULL);
            bResult = TRUE;
        }
    }
    return bResult;
}

template<class TYPE>
class CTypedSimpleList : public CSimpleList
{
public:
    CTypedSimpleList(int nNextOffset = 0)
        : CSimpleList(nNextOffset) { }
    void AddHead(TYPE p)
    { CSimpleList::AddHead(p); }
    TYPE GetHead()
    { return (TYPE)CSimpleList::GetHead(); }
    TYPE GetNext(TYPE p)
    { return (TYPE)CSimpleList::GetNext(p); }
    BOOL Remove(TYPE p)
    { return CSimpleList::Remove((TYPE)p); }
    operator TYPE()
    { return (TYPE)CSimpleList::GetHead(); }
};

class AFX_NOVTABLE CNoTrackObject
{
public:
    void* PASCAL operator new(size_t nSize)
    {
        void* p = ::LocalAlloc(LPTR, nSize);
//         if (p == NULL)
//             AfxThrowMemoryException();
        return p;
    }

    void PASCAL operator delete(void* p)
    {
        if (p != NULL)
            ::LocalFree(p);
    }
    
    void PASCAL operator delete(void* pObject, LPCSTR, int)
    {
        if (pObject != NULL)
            ::LocalFree(pObject);
    }

    virtual ~CNoTrackObject() { }
};


struct CThreadData : public CNoTrackObject
{
    CThreadData* pNext; // required to be member of CSimpleList
    int nCount;         // current size of pData
    LPVOID* pData;      // actual thread local data (indexed by nSlot)
};


int main(int argc, char* argv[])
{
    CTypedSimpleList<CThreadData*> m_list;  // list of CThreadData structures
    m_list.Construct(offsetof(CThreadData, pNext));

    for (int i = 0; i < 10; i++)
    {
        CThreadData *p = new CThreadData;
        p->nCount = i;
        p->pData = NULL;
        m_list.AddHead(p);
    }

    CThreadData *p = m_list.GetHead();
    while (p != NULL)
    {
        printf("%d ", p->nCount);
        p = p->pNext;
//        p = m_list.GetNext(p);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/licb/p/simplelist.html