首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C/C++ 通用物件鏈表實作指南:虛擬鏈表與 C++ 類別封裝完整方案

     編輯:關於C++

問題背景:同質異結構的程式碼重複困境

假設有兩個結構僅差一個欄位:

struct Struct_Object_A { int a, b; Struct_Object_A *next; };
struct Struct_Object_B { int a, b, c; Struct_Object_B *next; };

雖然邏輯相同,編譯器視為完全不同型別,導致新增、刪除、搜尋等函式必須重複撰寫。傳統解法使用聯合或冗餘欄位,但會造成程式碼膨脹與維護困難。

C 語言方案:虛擬鏈表

核心概念

虛擬鏈表節點僅包含指標,實際資料儲存在節點結構之後的記憶體區塊:

typedef struct liststruct { liststruct *next; } LIST, *pLIST;

pLIST AddToList(pLIST Head, void *data, size_t datasize) {
    pLIST newlist = (pLIST)malloc(datasize + sizeof(LIST));
    void *p = (void*)(newlist + 1);  // 指向資料區
    memcpy(p, data, datasize);       // 複製資料
    newlist->next = Head;
    return newlist;                  // 新節點成為表頭
}

進階:支援解構函式的虛擬鏈表

為處理動態配置記憶體的物件(需釋放資源),節點加入解構函式指標:

typedef void (*ListNodeDestructor)(void*);
typedef struct liststruct {
    ListNodeDestructor DestructFunc;
    liststruct *next;
} LIST, *pLIST;

void DeleteList(pLIST Head) {
    while (Head) {
        pLIST Next = Head->next;
        Head->DestructFunc((void*)Head); // 呼叫自訂清理邏輯
        free(Head);
        Head = Next;
    }
}

測試案例展示字串資料的正確配置與釋放流程。

C++ 方案:類別封裝鏈表

設計架構

  • 基底結構 ND_LIST 僅含 next 指標
  • CList 類別繼承 ND_LIST,封裝單一資料型別的解構函式
  • 提供 GetCurrentData() 完成節點指標到資料偏移的轉換

核心實作

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, m_CurrentNode;
    ListNodeDestructor m_DestructFunc;
};

// 關鍵:節點指標轉資料指標的數學運算
void *CList::GetCurrentData() {
    return (void*)(m_CurrentNode + 1); // 跳過節點結構體大小
}

使用範例

CList* pList = new CList(ClassListDataDestructor);
pND_LIST_DATA d = new LIST_DATA;
d->p = new char[24];
strcpy(d->p, "Hello");
pList->AddToList((void*)d, sizeof(pND_LIST_DATA));
delete d; // 原物件可刪除,資料已複製至鏈表節點

設計優勢與擴充性

  • 型別無關:同一鏈表可存放任意異構物件(需區分型別時可檢查解構函式指標或加入型別標籤)
  • 記憶體效率:單一配置同時取得節點與資料空間,減少碎片
  • 可擴充性:易於加入排序、搜尋、反轉等功能,一次撰寫、到處復用
  • 專案實證:作者實際專案中處理約 20 種不同物件型別

總結

虛擬鏈表透過「節點前置、資料後置」的記憶體佈局,配合函式指標實現多型銷毀,完美解決 C/C++ 靜態型別系統下的通用容器難題。C++ 封裝進一步提升型別安全與介面清晰度。這套架構雖初期投入較大,但長期效益極高,是系統級程式設計的經典模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved