最近将一个开源项目port到嵌入式设备上,发现其巨大部分类都是继承于双向链表(或者双向队列),这一个过程看似不可思议(感觉有违我们以前学的面向对象的知识),但是事实却是这样的方式使很多操作都变得简单起来,由于类继承于Link,则在Link类中不需要用特定的变量指向特定的数据,而这一过程在使用这个类的时候已近默认的实现。以前读本科的时候,也只是了解到了双向循环链表的理论,没有实现,今天乘这个机会把它搞定。
对于类MprLink, 具有两个成员变量(MprLink* prev 和 MprLink * next),三个主要的函数,构造函数MprLink, insertAfter, insertPrior.
构造函数: MprLink(),在构造函数中将prev和next都指向对象自己(通过this指针),则一个循环链表就构成了。
insertAfter:
函数原型void MprLink::insertAfter(MprLink *item) ;
如下图所示,有两个MprLink的实体(假设实体名分别为linkA, linkB),调用过程很简单,即linkA.insertAfter(linkB),那么他们调用的具体过程是如何实现的呢?
step1. 在调用之前,linkA,linkB的结构如图所示
step2.将linkA的next指针的pre指针的内容指向linkB
next->prev = linkB;
step3.将linkB的prev指针指向linkA
linkB->prev = this;
step3.将linkB的next指针指向linkA的next指针所指向的项
linkB->next = next;
step4.将linkA的next指向linkB
next = linkB;
完成,一个简单的双向循环链表就形成了,其具体代码如下:
inline void MprLink::insertAfter(MprLink *item) {
inlineAssert(item->head == 0);
item->head = head;
next->prev = item;
item->prev = this;
item->next = next;
next = item;
head->numItems++;
}
insertPrior函数与insertAfter的实现相似,代码实现如下:
inline void MprLink::insertPrior(MprLink *item) {
inlineAssert(item->head == 0);
item->head = head;
prev->next = item;
item->next = this;
item->prev = prev;
prev = item;
head->numItems++;
}
其实看到这里,大家可能觉得这只是简单的链表操作,没有什么新奇的,哈哈,其实这只是MprLink的一个简化版本,它的实现其实还与其派生类MprList相关,等讲了MprList的实现之后,我们就可以看到了这个类功能的强大。