2013-08-05 42 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。 –