2012-07-26 72 views
0

我已經對dynamic_casting做了一點研究,並且我讀到它創建了一個叫做RTTI的東西, 它在啓動時也加載到RAM中。在一些平臺上,我認爲這也不被支持。所以我想知道是否有任何好的解決方案來避免它。C++如何避免dynamic_casting?

比方說,我有Statement類

class Statement 
{ 
    std::list<Operand*> operands; 
}; 

和操作數與一個以上副類喜歡,內存地址,註冊,ECT類。 (對於一些想知道的問題,我正在嘗試編譯一個彙編程序:P

我不能用dynamic_cast去downcasting,如果可以的話,這也是不好的。但是如果我爲操作數添加了一個枚舉,它定義了類型,所以我可以用它的類型與的static_cast垂頭喪氣。

我可以讓它變成一個常量,並在每個子類的構造函數定義是正確的?

我期待着你所有的想法。

基督教

+7

理想情況下,您只需依賴多態性,而不關心對象的具體類型。爲什麼認爲你需要向下轉換? – 2012-07-26 07:43:48

+0

彙編程序應在哪個平臺上運行?如果它應該在開發人員的計算機上運行,​​那麼可以肯定RTTI的影響是可以忽略的。如果它應該在(非常)低規格的嵌入式目標上運行,那麼你就在正確的道路上。現在我覺得你錯誤地使用了dynamic_cast。對於常見的OOP任務,應該不需要dynamic_cast,只需使用基類中定義的方法即可。 – 2012-07-26 07:45:01

+0

我同意@BjörnPollex。如果您的問題無法通過類型轉換來解決,那麼類設計可能是錯誤的。但如果你不在意,我建議你參與訪問者模式。但請注意,此模式提供與枚舉相同的功能,並且通常會導致組件共用 – 2012-07-26 07:54:42

回答

2

製作一個類型 - 是一個選項。

但是考慮爲Operand製作通用interface。所以你的memory addressregister等eple將實現該接口,你將能夠對待他們多態。

如果你不能發明這樣的interface - 考慮重新設計你的類,因爲它看起來不需要有一個通用接口。

如果你需要的代碼重用 - 去composition,不inheritance

2

如果你決定要投下來,你可以考慮使用的接口,用於爲適當的類型。但是,您也可以顯式列出子類。

class Operand { 
public: 
    enum Type { OT_Address, OT_Register, /*...*/ }; 
    virtual Type type() const = 0; 
    virtual AddressOperand * isAddress() { return 0; } 
    virtual RegisterOperand * isRegister() { return 0; } 
    //... 
}; 

然後,您可以簡單地調用與該類型關聯的方法,而不是使用downcast。派生類將實現它:

class AddressOperand : public Operand { 
public: 
    Operand::Type type() const { return Operand::OT_Address; } 
    AddressOperand * isAddress() { return this; } 
    //... 
};