Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->Linux程序设计 ->正文

在 C/C++中怎么样构造通用的对象链表

来源:IBM DW中国 作者:T. W. Burger  时间:2007-04-22 点击: [收藏] [投稿]

C++ 解决方案:类链表

本解决方案将 CList 类定义为从 LIST 结构导出的一个类,它通过存储解除函数的单个值来处理单个存储类型。请注意添加的 GetCurrentData() 函数,该函数完成从链表节点指针到数据偏移指针的数学转换。


一个虚拟链表对象


// 定义解除函数指针

typedef void (*ListNodeDestructor)( void * );

// 未添加解除函数指针的链表

typedef struct ndliststruct
{
    ndliststruct *next;

} ND_LIST, *pND_LIST;

// 定义处理一种数据类型的链表类

class CList : public ND_LIST
{
public:
    CList(ListNodeDestructor);
    ~CList();
    pND_LIST AddToList( void * data, size_t datasize );
    void *GetCurrentData();
    void DeleteList( pND_LIST Head );


private:
    pND_LIST m_HeadOfList;
    pND_LIST m_CurrentNode;
    ListNodeDestructor m_DestructFunc;
};

// 用正确的起始值构造这个链表对象

CList::CList(ListNodeDestructor Destructor)
    : m_HeadOfList(NULL), m_CurrentNode(NULL)
{
    m_DestructFunc = Destructor;
}

// 在解除对象以后删除链表

CList::~CList()
{
    DeleteList(m_HeadOfList);
}

// 向链表中添加一个新节点

pND_LIST CList::AddToList( void * data, size_t datasize )
{
pND_LIST newlist=NULL;
void *p;


    // 分配节点内存和数据内存
    newlist = (pND_LIST) malloc( datasize + sizeof( ND_LIST ) );

    // 为这块数据缓冲区指定一个指针
    p = (void *)( newlist + 1 );

    // 复制数据
    memcpy( p, data, datasize );

    // 将这个节点指定给链表的表头
    if( m_HeadOfList )
    {
        newlist->next = m_HeadOfList;
    }
    else
        newlist->next = NULL;

    m_HeadOfList = newlist;

    return m_HeadOfList;
}

// 将当前的节点数据作为 void 类型返回,以便调用函数能够将它转换为任何类型

void * CList::GetCurrentData()
{
    return (void *)(m_CurrentNode+1);
}

// 删除已分配的链表

void CList::DeleteList( pND_LIST Head )
{
    pND_LIST Next;
    while( Head )
    {
        Next = Head->next;
        m_DestructFunc( (void *) Head );
        free( Head );
        Head = Next;
    }
}

// 创建一个要在链表中创建和存储的结构

typedef struct ListDataStruct
{
    LPSTR p;

} LIST_DATA, *pND_LIST_DATA;

// 定义标准解除函数

void ClassListDataDestructor( void *p )
{
    // 对节点指针进行类型转换
    pND_LIST pl = (pND_LIST)p;

    // 对数据指针进行类型转换
    pND_LIST_DATA pLD = (pND_LIST_DATA) ( pl + 1 );

    delete pLD->p;
}

// 测试上面的代码

void MyCListClassTest()
{
    // 创建链表类

    CList* pA_List_of_Data = new CList(ClassListDataDestructor);

    // 创建数据对象
    
    pND_LIST_DATA d = new LIST_DATA;
    d->p = new char[24];
    strcpy( d->p, "Hello" ); 

    // 创建指向链表顶部的局部指针

    pND_LIST Head = NULL;

    //向链表中添加一些数据

    Head = pA_List_of_Data->AddToList( (void *) d, 
    sizeof( pND_LIST_DATA ) );
    // 该对象已被复制,现在删除原来的对象
    delete d;

    // 确认它已被存储
    char * p = ((pND_LIST_DATA) pA_List_of_Data->GetCurrentData())->p;

    d = new LIST_DATA;
    d->p = new char[24];
    strcpy( d->p, "World" ); 
    Head = pA_List_of_Data->AddToList( (void *) d, sizeof( pND_LIST_DATA ) );
    // 该对象已被复制,现在删除原来的对象
    delete d;

    // 确认它已被存储
    p = ((pND_LIST_DATA) pA_List_of_Data->GetCurrentData())->p;

    // 删除链表类,析构函数将删除链表
    delete pA_List_of_Data;
}

 

小结

从前面的讨论来看,似乎仅编写一个简单的链表就要做大量的工作,但这只须进行一次。很容易将这段代码扩充为一个处理排序、搜索以及各种其他任务的 C++ 类,并且这个类可以处理任何数据对象或类(在一个项目中,它处理大约二十个不同的对象)。您永远不必重新编写这段代码。

原文链接:http://www.ibm.com/developerworks/cn/linux/l-tip-prompt/tip02/index.html



 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:Python anygui 项目预览   下一篇:用C语言实现Ping程序功能

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号