递归检查超类type_info

问题描述:

有没有办法检查超类的type_info是什么? 在我的系统中,对象由一组位标识。哪一个由type_info哈希码标识。我希望其中的一些类型能够启用多态,因为我的系统认为它们处于相同位置。 type_info为每个类类型创建一个唯一的哈希码。相反,我想派生类取位设置其超类的,像这样:递归检查超类type_info

Component > ISomeInterfaceComponent -> bit = 00001 
       | 
       \ ComponentContextA -> bit = ISomeInterFaceComponent bit 
       | 
       \ ComponentContextB -> bit = ISomeInterFaceComponent bit 
       | 
       \ ComponentContextC -> bit = ISomeInterFaceComponent bit 

这应该包含组件的对象添加到一个系统中进行处理。

截至目前,这是发生了什么:

Component > ISomeInterFaceComponent -> bit = 00001 
       | 
       \ ComponentContextA -> bit = 00010 
       | 
       \ ComponentContextB -> bit = 00100 
       | 
       \ ComponentContextC -> bit = 01000 

这就要求我为所有的组件不同的系统。

如果任何人都可以给我指点我如何才能实现这将是伟大的。

编辑: 为了防止混淆得到一个类型的位设置如下: ComponentTypeManager :: getBit();

所以我没有使用实例。我希望保持当前系统的锁定状态。

+0

相关[抓狂黑客答案】(http://*.com/a/11675891/168175)我写的 “我能做到这一点,只需TYPE_INFO”? – Flexo 2012-07-27 22:11:27

+0

C++ 11提供了一个is_base_of模板来执行相同的操作。但是在我的情况下创建数十个if/else是不实际的。我真的觉得我需要重新设计一些方法。 – Sidar 2012-07-28 00:16:05

没有,我所知道的任何自动方式。但是,如果我理解你,可以通过一点额外的努力来完成。

对于每个“基本”类,添加一个引用自身的typedef,并将其用于typeid()。请注意,子类可以选择覆盖它。如果他们这样做,那么他们会得到自己的ID,他们的孩子将会使用他们的价值。

请注意,如果您完全不想使用typeid(),则另一个解决方案是在基类上具有一个静态成员(或成员函数),该静态成员为基数返回适当的值,然后直接在你的getBit()函数。

#include <iostream> 
#include <iomanip> 
#include <typeinfo> 

struct Base1 
{ 
    typedef Base1 Base; 

}; 

struct Base2 
{ 
    typedef Base2 Base; 
}; 

struct Derived1A : public Base1 { }; 
struct Derived1B : public Base1 { };  
struct Derived2A : public Base2 { };  
struct Derived2B : public Base2 { }; 

template <typename T> 
std::size_t getBit() 
{ 
    // Do whatever you normally do here, but use T::Base instead of T 
    return std::hash<std::string>()(typeid(typename T::Base).name()); 
} 

int main() 
{ 
    std::cout << std::boolalpha << getBit<Derived1A>() << " == " << getBit<Derived1B>() << " " << (getBit<Derived1A>() == getBit<Derived1B>()) << "\n"; 

    std::cout << std::boolalpha << getBit<Derived2A>() << " == " << getBit<Derived2B>() << " " <<(getBit<Derived2A>() == getBit<Derived2B>()) << "\n"; 

} 

http://ideone.com/6ad08

+0

感谢您的回复。但我没有看到这个工作,因为所有东西都是从一个Component类派生的,这个类派生了一个基本的多态性。我想我不得不重新设计它。 – Sidar 2012-07-27 22:19:53

+0

@Sidar:嗯,它应该仍然有效。没有什么能够阻止Base1和Base2拥有共同的超类型。 – 2012-07-28 02:35:19

为什么不在基类ISomeInterFaceComponent中创建一个未被任何派生类修改的变量(除非您特别需要它)。它听起来并不像你想要的多态性,因为你希望位值是相同而不管派生类的类型,而不是基于类型而变化。如果将来您需要重写,如果对于某个派生类型,您仍然可以专门为该类执行此操作。

或者,您可以在基类中使用一个返回int值的虚函数(位值 - 或者实际上是任何类型的值),并且不要在派生类中重写它,而您想要具有相同的位值作为基地。

例如

class ISomeInterFaceComponent { 
     virtual int GetBit() { return 1;}; // return bit value 
}; 


class ComponentContextA : public ISomeInterFaceComponent { 
     // Do not override GetBit() - let the base class function get called. 
}; 
+0

因为类型不是由实例定义的,而是由它们的实际类名定义的。 获取一个位类型如下:ComponentTypeManager :: getBit (); 我没有在这种情况下使用实例。我直接和班级一起工作。 – Sidar 2012-07-27 21:09:39

+0

@Sidar - 我明白了。在那种情况下,我不知道。抱歉。 – mathematician1975 2012-07-27 21:11:39