void TestList() { pLIST_DATA d = new LIST_DATA; d->p = new char[24]; strcpy( d->p, "Hello" ); Head = AddToList( Head, (void *) d, sizeof( pLIST_DATA ), ListDataDestructor ); // 该对象已被复制,现在删除原来的对象 delete d;
d = new LIST_DATA; d->p = new char[24]; strcpy( d->p, "World" ); Head = AddToList( Head, (void *) d, sizeof( pLIST_DATA ), ListDataDestructor ); delete d;
// 释放链表 DeleteList( Head ); }
在每个链表节点中包含同一个解除函数的同一个指针似乎是浪费内存空间。确实如此,但只有链表始终包含相同的对象才属于这种情况。按这种方式编写链表答应您将任何对象放在链表中的任何位置。大多数链表函数要求对象总是相同的类型或类。虚拟链表则无此要求。它所需要的只是将对象彼此区分开的一种方法。要实现这一点,您既可以检测解除函数指针的值,也可以在链表中所用的全部结构前添加一个类型值并对它进行检测。当然,假如要将链表编写为一个 C++ 类,则对指向解除函数的指针的设置和存储只能进行一次。
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 );
void CList::DeleteList( pND_LIST Head ) { pND_LIST Next; while( Head ) { Next = Head->next; m_DestructFunc( (void *) Head ); free( Head ); Head = Next; } }
// 确认它已被存储 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++ 类,并且这个类可以处理任何数据对象或类(在一个项目中,它处理大约二十个不同的对象)。您永远不必重新编写这段代码。
参考资源
* The linux C Programming Lists 旨在帮助人们用 C 语言进行 Linux 编程,其中包括许多到邮件列表、常见问题解答、教程以及其他内容的链接。 * Microsoft Foundation Class 在其 CList 类中提供了类似的功能。MFC 中的 CList 以及别的类要求类型或类只能是一种类型,程序员对代码没有控制权,这一点与从零开始构建链表不同。
作者简介 Thomas Wolfgang Burger 是 Thomas Wolfgang Burger Consulting 公司的老板。自 1978 年以来,他做过咨询人员、教师、分析员和应用程序开发员。可以通过 twburger@bigfoot.com 与他联系。
您对这篇文章的看法如何?
真棒! 好文章 一般,尚可 需提高 太差!
意见
(c) Copyright IBM Corp. 2001, (c) Copyright IBM China 2001, All Right Reserved 隐私 法律 联系