2012-05-11 81 views
2

我有一個設計問題,我不知道如何以最佳方式處理。我希望我的代碼能夠成爲未來的證明,並且不會混亂和複雜(怪胎的困境)。dynamic_cast和多態性的最佳做法

目前我的設計有以下設置

derived class D   derived class E 
^      ^
    |       | 
derived abstract class B ->    derived class C 
^          ^
    |           | 
       Abstract Base class A 

BA階級,階層D和類EB類不同,CA類的不同而不同。

由於這些類不同,我需要使用dynamic_cast運算符。

A* a1 = new class C; 
C* c1 = dynamics_cast<C*>(a1); 
if(c1){ //Success!!!} 
... 

正如你所看到的,我會想要使用dynamic_cast很多!我需要嘗試找到一個不錯的方法來做到這一點,但這不是完整的if()聲明。

有沒有一個乾淨的方式做到這一點?我似乎記得在Scott Meyers的書中看到了一些東西,但我離家很遠,無法訪問它一兩個星期。

任何參考資料/例子將不勝感激。

而且如果需要的話我可以讓B類到這將是一個類型的解決

B* d1 = new D; 
B* e1 = new E; 

但不理想的接口。

注:我加入這個例子來說明我目前的設計失敗

class A {...}; 

class B: public A { 
    public: 
     virtual std::vector<objectType1*>& getObjectType1(); 
}; 

class C: public B { 
    private: 
    void newFunction(); 
}; 

A* c1 = new C(); 
std::vector<objectType1*> example = c1->getObjectType1(); // Wrong; need dyanmic_cast :-(

沒有dynamic_cast不能訪問getObjectType1()的靜態類型A不知道這個功能。我需要重新思考我的設計。有任何想法嗎?

+0

你似乎使用不同的意思是繼承,你沒有給我們關於爲什麼你需要沮喪的細節 - 你只是假設你需要。爲什麼? –

+3

使用虛擬功能。 –

+1

如果他們在某種程度上沒有「不同」,那麼就不會有任何問題,但是您意味着什麼重要的方式?如果你的意思是他們在提供額外的無關功能方面有所不同,並且你不想要一個胖接口,那麼這是不尋常的,醜陋但有效的,'dynamic_cast <>'可能是合理的。 'if(C * p = dynamic_cast (a1))...'是一個更簡潔,更好的範圍表示法。儘管如此,「B類接口是一種解決方案」對我來說毫無意義 - 你應該解釋你在每個類中放置了什麼類型的函數,因爲你可能做錯了。 –

回答

10

在正確設計的對象層次結構中,使用dynamic_cast是非常罕見的。當然,它存在於多態樹上,但這並不意味着你必須使用它。

想想這個。一般來說,爲什麼你需要使用dynamic_cast?因爲你有的基地指針沒有提供你需要的設施,對吧?多態性有什麼意義?爲類似的操作提供不同的行爲,在運行時選擇行爲,對嗎?

這兩個陳述有些矛盾嗎?如果對象的界面設計正確,那麼當您撥打->Foo()時,您並不在乎將採用何種行爲 - 您只需撥打->Foo()即可。

如果您需要頻繁使用dynamic_cast,這是一種代碼異味,告訴您接口有問題。也許你試圖在一個界面中插入太多內容?

+1

這正是我所做的!重新思考肯定是需要的,我會編輯我的問題。展示我的確切設計庫。 – MWright