面向對象三大特性——封裝、繼承、多態——是 C++ 相較於面向過程語言的核心優勢。本文將以「鏈式表」為例,示範如何運用這三大特性,從零構建一個具備自動記憶體管理、迭代器遍歷、泛型支援的現代化 C++ 容器。
鏈表與線性表(陣列)最大的不同在於邏輯結構不連續,而是透過「前驅-後繼」指標串聯節點。優點在於插入/刪除效率高(O(1)),適合頻繁增刪的場景;缺點是隨機訪問需 O(n)。鏈表節點通常在堆區動態分配,需手動管理記憶體。
_data、_nextNodedata() 回傳副本、ref() 回傳引用)、下一節點操作繼承抽象基類 Sequence,實現:
_list_head、_list_tail)加速尾插push_back、pop、at、remove、operator[]_length、空表判斷 isEmpty()iterator()next()、hasNext()、data()、前置/後置 ++ 運算子_list 與游標 pointTo// 尾插優化:O(1)
void push_back(const T& val) {
++_length;
if (!_list_head) _list_head = _list_tail = new Node(val);
else _list_tail = new Node(val, *_list_tail);
}
// 刪除節點:處理頭節點與中間節點
bool remove(const rank pos) {
if (pos >= _length) return false;
--_length;
if (pos == 0) { /* 刪頭 */ }
else { /* 遍歷至 pos-1,重鏈接並 delete */ }
return true;
}
ZLinkedList<int> list; list.push_back(2); list.push_back(3); list.push_back(5); auto it = list.iterator(); while (it.hasNext()) cout << it.data() << endl, ++it; list.remove(0); it = list.iterator(); // 迭代器失效需重置 while (it.hasNext()) cout << it.data() << endl, ++it;

class Student { /* name, age, display() */ };
ZLinkedList<Student> list;
list.push_back(Student("zz", 19));
list.push_back(Student("ee", 20));
list.push_back(Student("ff", 21));
// 迭代遍歷並呼叫 display()

測試結果顯示:封裝正確、迭代器行為符合預期、記憶體管理無洩漏。
~ZLinkedList() 循環 remove(0) 釋放所有節點。完整頭檔 ZLinkedList.hpp 已整理於文末,可直接納入專案使用。