最近將一個開源項目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的實現之後,我們就可以看到了這個類功能的強大。