关于C++中RTTI的编码实现
摘要:
RTTI(Run-Time Type Identification)是面向对象程序设计中一种重要的技术。现行的C++标准对RTTI已经有了明确的支持。不过在某些情况下出于特殊的开发需要,我们需要自己编码来实现。本文介绍了一些关于RTTI的基础知识及其原理和实现。
实现目标:
实现的方案
方案一:利用多态来取得指针或应用的实际类型信息
这是一个最简单的方法,也是作者目前所采用的办法。
实现:
enum ClassType{
UObjectClass,
URectViewClass,
UDialogClass,
……
};
class UObject{
virtual char* GetClassName() const {
return "UObject";
};
virtual ClassType TypeOfClass(){
return UObjectClass;
};
};
class UDialog{
virtual char* GetClassName() const {
return "UDialog";
};
virtual ClassType TypeOfClass(){
return UDialogClass;
};
}; |
示例:
UObject po=new UObject;
UObject pr=new URectView;
UObject pd=new UDialog;
cout << "po is a " << po->GetClassName() << endl;
cout << "pr is a " << pr->GetClassName() << endl;
cout << "pd is a " << pd->GetClassName() << endl;
cout<TypeOfClass()==UObjectClass< cout<TypeOfClass()==URectViewClass<TypeOfClass()==UDialogClass<TypeOfClass()==UObjectClass<TypeOfClass()==UDialogClass< |
输出:
po is a UObjectClass
pr is a URectViewClass
pd is a UDialogClass
true
true
true
false
false |
这种实现方法也就是在基类中提供一个多态的方法,这个方法返回一个类型信息。这样我们能够知道一个指针所指向对象的具体类型,可以满足一些简单的要求。
但是很显然,这样的方法只实现了typeid的部分功能,还存在很多缺点:
1、 用户每增加一个类必须覆盖GetClassName和TypeOfClass两个方法,如果忘了,会导致程序错误。
2、 这里的类名和类标识信息不足以实现dynamic_cast的功能,从这个意义上而言此方案根本不能称为RTTI。
3、 用户必须手工维护每个类的类名与标识,这限制了以库的方式提供给用户的可能。
4、 用户必须手工添加GetClassName和TypeOfClass两个方法,使用并不方便。
其中上面的部分问题我们可以采用C/C++中的宏技巧(Macro Magic)来解决,这个可以在我们的最终解决方案的代码中看到。下面采用方案二中将予以解决上述问题
其他的方案我忘记了 呵呵 不好意思