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

C++ 進階實戰:帶虛繼承的 Collection 體系設計與實現(D&A 5)

     編輯:關於C++

題目需求拆解

實現一個支持多態的容器體系:

  • Collection、List 為抽象基類(含純虛函數)。
  • ArrayList、LinkedList 繼承 List。
  • Stack、Queue 通過模板模板參數適配任意 Container(預設 SeqList)。
  • 涉及虛繼承解決菱形問題、純虛析構函數、模板分離編譯等硬核考點。

關鍵技術點深度解析

1. 虛繼承消除菱形冗餘

class Animal { virtual void eat(); };
class Mammal : public virtual Animal { virtual void breathe(); };
class Winged : public virtual Animal { virtual void flap(); };
class Bat : public Mammal, public Winged { };

內存佈局:Bat 僅包含一份 Animal 子物件。編譯器通過 vbptr(虛基類表指針)在運行時定位共享基類,代價是對象體積增加指針、訪問多一次間接寻址。

2. 純虛析構函數:抽象類的正確析構協議

class Collection {
public:
    virtual ~Collection() = 0;  // 純虛析構
    virtual void add(Object*) = 0;
};
Collection::~Collection() {}  // 必須提供定義!

鐵律:只要類含有虛函數,析構函數必須聲明為 virtual。純虛析構強制子類實現,且基類必須給出定義(否則鏈接錯誤)。

3. 模板模板參數實現容器適配器

template  class Container = SeqList>
class Stack {
    Container _con;  // 組合而非繼承
public:
    void push(const T& x) { _con.push_back(x); }
    void pop() { _con.pop_back(); }
    const T& top() const { return _con.back(); }
};

Container 必須是接受單一類型參數的模板(如 SeqList、std::vector、std::deque),實現「策略模式」的編譯期綁定版本。

4. 模板分離編譯:.hpp 一體化方案

模板聲明與定義必須對編譯器可見。標準做法:

  • 所有代碼寫在 xxx.hpp(或 .inl 包含在 .h 末尾)。
  • 不寫 .cpp,避免「未定義引用」鏈接錯誤。

常見坑點與調試經驗

現象原因修正
Linker error: duplicate symbol同名函數在多個 .cpp 中實例化改用 .hpp 一體化、或 inline、或顯式實例化
Stack overflow遞歸深度過大 / 局部大對象改迭代、用動態分配、增大棧大小
虛基類訪問錯誤構造順序誤解(虛基類最先構造)最派生類構造函數初始化列表直接調用虛基類構造函數

重構建議

  1. 優先用 std::vector/std::list 替換手寫容器,專注適配器邏輯。
  2. 引入 std::unique_ptr 管理元素所有權,避免裸指針洩漏。
  3. 用 static_assert 檢查 Container 滿足所需接口(C++20 Concepts 更佳)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved