dynamic_cast 與 operator override 的應用

假設我有一個 Interface 如下

struct IProperty abstract
{
 ~IProperty() { }

 virtual LPCTSTR toString() = 0;

 virtual BOOL operator==(const IProperty& other) const = 0;
 virtual BOOL operator!=(const IProperty& other) const = 0;

};


然後有一個 class 實作該 Interface

class InstrumentType : public IProperty
{
public:
 enum INSTRUMENTTYPE
 {
  GUITAR,
  BANJO,
  DOBRO,
  FIDDLE,
  BASS,
  MANDOLIN,
 };

private:
 INSTRUMENTTYPE m_enInstrumentType;

public:
 InstrumentType(INSTRUMENTTYPE enInstrumentType);
 ~InstrumentType(void);

 LPCTSTR toString();

 BOOL operator==(const IProperty& other) const;
 BOOL operator!=(const IProperty& other) const;
};

那在 operator== 函式中,如何將 other 從 IProperty& 轉換成 InstrumentType& 呢?

第一個想法是

 PInstrumentType pOtherInstrumentType = dynamic_cast<PInstrumentType>(&other);

不過得到的結果是

error C2682: cannot use 'dynamic_cast' to convert from 'const IProperty *' to 'PInstrumentType'


如果改用 Reference 的方式轉換

 InstrumentType& OtherInstrumentType = dynamic_cast<InstrumentType&>(other);

還是錯誤

error C2682: cannot use 'dynamic_cast' to convert from 'const IProperty &' to 'InstrumentType &'


最後測試的結果是要加上 const,也就是轉換前後都要一樣才行


BOOL InstrumentType::operator==(const IProperty& other) const
{
 const InstrumentType& OtherInstrumentType = dynamic_cast<const InstrumentType&>(other);

 return (m_enInstrumentType == OtherInstrumentType.m_enInstrumentType);
}

先前也有想過用 const_cast 的方式,不過它的用途是把 const 的修飾功能移除 (變成非 const 變數) 所以要經過兩次轉換才能達到目的

 IProperty& other1 = const_cast<IProperty&>(other);
 InstrumentType& OtherInstrumentType = dynamic_cast<IinstrumentType&>(other1);

經過這一次的實驗,對安全型別轉換 dynamic_cast 也有更深一層的認識
  1. 轉換前後的修飾字元必須完全一致
  2. 除了指標外,也可以轉換 Reference

留言

這個網誌中的熱門文章

Linux 批次檔的寫法

【分享】如何顯示 Debug Message

[分享] Visual Studio 遠端偵錯