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

C++ 代理類設計模式詳解:解決容器存儲異構對象難題

     編輯:C++ 入門

C++ 代理類設計模式詳解:解決容器存儲異構對象難題

問題背景

在 C++ 中,容器(如數組)通常只能存儲單一類型的對象。若需存儲繼承自同一基類的不同派生類對象(如 Vehicle、RoadVehicle、Aircraft 等),直接存儲對象會導致對象切片,丟失派生類特有成員;存儲指針雖能利用多態,卻引入動態內存管理負擔與生命週期控制難題。

經典解決方案:間接層

最早的方案是存儲基類指針(Vehicle* parking_lot[1000]),但面臨兩大問題:

  1. 懸空指針風險:指向局部變量的指針在變量銷毀後失效。解決方法是存儲對象副本的指針,並由容器負責釋放。
  2. 動態內存管理負擔:且無法處理編譯時類型未知的對象復制(如 parking_lot[p] = new Vehicle(*parking_lot[q]) 會導致切片)。

虛復制函數

在基類中引入純虛函數 virtual Vehicle* copy() const = 0,每個派生類實現為 return new Derived(*this)。配合虛析構函數 virtual ~Vehicle() {},即可實現運行時類型感知的深度復制。

代理類完整實現

class VehicleSurrogate {
public:
    VehicleSurrogate() : vp(0) {}
    VehicleSurrogate(const Vehicle& v) : vp(v.copy()) {}
    ~VehicleSurrogate() { delete vp; } // delete 空指針安全
    
    VehicleSurrogate(const VehicleSurrogate& v) 
        : vp(v.vp ? v.vp->copy() : 0) {}
    
    VehicleSurrogate& operator=(const VehicleSurrogate& v) {
        if (this != &v) {
            delete vp;
            vp = v.vp ? v.vp->copy() : 0;
        }
        return *this;
    }
private:
    Vehicle* vp;
};

核心機制解析

  • 構造函數:接受 const Vehicle&,利用多態調用正確的 copy() 創建副本
  • 空代理概念:默認構造函數創建 vp=0 的空代理,支持數組定義
  • 拷貝構造/賦值:深度復制被代理對象,處理自賦值與空指針
  • 析構函數:自動釋放持有的對象,無內存洩漏

使用示例

VehicleSurrogate parking_lot[1000];
Automobile x;
parking_lot[num_vehicles++] = x; // 等價於 parking_lot[...] = VehicleSurrogate(x);

此時會創建 x 的副本並由代理對象管理,數組銷毀時自動清理所有副本。代理類將整個繼承體系「壓縮」為單一類型,兼具值語義與多態行為,是 C++ 中實現異構容器的經典模式。

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