2013-08-05 53 views
3

假設我有一個較低的水平如何將信息附加到類層次結構?

class A {...}; 
class A0 : public A {...}; 
class A1 : public A {...}; 
class A2 : public A {...}; 

類層次結構,我要代表它像圖標的GUI級別較高的水平,這可能很容易在這些類中添加一個虛擬方法

virtual Icon A::icon() {return iconOfA;} 
virtual Icon A0::icon() {return iconOfA0;} 
virtual Icon A1::icon() {return iconOfA1;} 
virtual Icon A2::icon() {return iconOfA2;} 

但是,我不想改變低級別的類,任何簡單的方法來實現它?我希望能動態地使用它,就像

A* a = new A2(); 
getIcon(a); // will return iconOfA2. 

謝謝。

+0

在基類A中聲明'icon'作爲虛函數。並且geticon獲取基類指針或引用,並調用該基類變量上的圖標。 –

+0

這就是我不想要的問題,如我的問題所示。 – user1899020

+0

這需要重寫派生類中的圖標()OP要避免的操作 – 4pie0

回答

3
Icon getIcon(A* a_ptr){ 
    A0* a0_ptr = dynamic_cast<A0*>(a_ptr); 
    if(a0_ptr){ 
     return iconOfA0; 
    } 
    A1* a1_ptr = dynamic_cast<A1*>(a_ptr); 
    if(a1_ptr){ 
     return iconOfA1; 
    } 
    A2* a2_ptr = dynamic_cast<A2*>(a_ptr); 
    if(a2_ptr){ 
     return iconOfA2; 
    } 
    return Icon(); 
} 

或者申報圖:基於RTTI

typedef std::map<const type_info*, Icon> Iconmap; 
Iconmap iconmap; 

//... 
iconmap.insert(std::make_pair(&typeid(A0), Icon())); 
iconmap.insert(std::make_pair(&typeid(A1), Icon())); 
iconmap.insert(std::make_pair(&typeid(A2), Icon())); 
//... 

和返回圖標:

Icon getIcon(A* ptr){ 
    Iconmap::iterator it = iconmap.find(&typeid(*ptr)); 
    if(it!=iconmap.end()){ 
     return (*it).second(); 
    }else{ 
     return Icon(); 
    } 
} 
1

使用RTTI:

if (typeid(*a).name()==typeid(A0).name()) return iconOfA0; else if 
(typeid(...... 
+0

這種方法可行,但與簡單的多態方法相比可能難以維護。有更好的方法嗎? – user1899020

0

一種方式做,這將是在基類A.這應該是公共或保護的圖標數據字段,以便它在派生類訪問。然後,每個類的構造函數可以將該值設置爲它們自己的圖標版本。 getIcon方法將始終返回正確類型的玻璃圖標,並且該方法只需要在基類中定義。

5

創建在GUI級別的地圖,將有類鍵和圖標價值。圖標屬於圖形用戶界面,它可能與課程本身無關。

+2

+1 - 關注點的分離是一個非常重要且經常被忽視的概念 – SteveLove

+0

如何實現它,特別是對於擁有類的關鍵? – user1899020

+1

在層次結構中的某個較高級別定義'classname'或使用rtti。 –