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

More Effective C++:不使用多態數組——切片問題的鐵律

     編輯:關於C++

問題根源:指針算術與對象大小不匹配

class BST { ... };
class BalancedBST : public BST { ... };
void printBSTArray(ostream&, const BST array[], int n);

調用 printBSTArray(cout, bBSTArray, 10) 編譯通過,但運行時錯誤:

  • 函數內 array[i] 展開為 *(array + i),指針增量按 sizeof(BST) 計算。
  • 實際傳入 BalancedBST 數組,元素大小為 sizeof(BalancedBST)(通常更大)。
  • 導致訪問越界、錯誤對象、析構函數調用錯亂,行為未定義。

刪除多態數組同樣災難

void deleteArray(ostream&, BST array[]);
BalancedBST* p = new BalancedBST[50];
deleteArray(cout, p); // 編譯器生成按 BST 大小步進調用 ~BST(),實際對象更大

結果:部分對象未正確析構、內存洩漏、堆損壞。

語言規範明確:行為未定義

C++ 標準規定:通過基類指針刪除派生類數組 → 未定義行為。

根治:避免從具體類派生具體類

  • 若 BST 為抽象接口類(純虛析構、無數據),則無實例化,自然無數組問題。
  • 具體類繼承具體類是多態數組陷阱的溫床,應盡量避免。

替代方案

  • 用指針/智能指針容器:std::vector<std::unique_ptr<BST>>。
  • 若必須連續存儲,使用型別擦除(如 std::variant、std::any)或固定大小緩衝區。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved