首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 多態:HuffTree 節點指針調用子類方法報錯解決

     編輯:程式設計綜合問答

問題

HuffNode<E>* Root 指向 LeafNode 或 IntlNode 實例,但通過 Root 調用子類特有方法(如 left()、val())編譯報錯「成員函數未定義」。

原因

Root 靜態類型為 HuffNode<E>*(基類指針),**編譯期只能看到基類接口**。子類特有方法不在基類虛函數表中。

解決方案

方案一:引入虛函數(推薦)

在基類聲明純虛函數,子類實現:


template <typename E>
class HuffNode {
public:
    virtual ~HuffNode() {}
    virtual int weight() = 0;
    virtual bool isLeaf() = 0;
    // 新增通用訪問接口
    virtual HuffNode<E>* left() { return nullptr; }
    virtual HuffNode<E>* right() { return nullptr; }
    virtual E val() { throw std::runtime_error("Not leaf"); }
};

template <typename E>
class LeafNode : public HuffNode<E> {
    // 實現 val()
    E val() override { return it; }
    // left/right 保持基類默認實現
};

template <typename E>
class IntlNode : public HuffNode<E> {
    // 實現 left/right
    HuffNode<E>* left() override { return lc; }
    HuffNode<E>* right() override { return rc; }
};

調用時:Root->left() 多態派發到 IntlNode::left()。

方案二:dynamic_cast 下轉型(不推薦常用)


if (auto* internal = dynamic_cast<IntlNode<E>*>(Root)) {
    internal->left(); // 安全調用子類方法
}

需基類有虛函數(已有虛析構函數即可),且開啟 RTTI。

設計原則

  • **面向接口編程**:基類定義完整行為契約,子類實現細節。
  • 避免在客戶代碼中 dynamic_cast,違反開閉原則。
  • 若子類確有獨有操作無法上提,考慮 Visitor 模式雙分發。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved