主要是参考下图,了解内存布局,然后写个实例程序就差不多明白了,但是需要熟悉指针转换。
1) 只有多态类才有RTTI信息,dynamic_cast正是运用RTTI进行转换,属于运行时类型检查。
2) dynamic_cast判断两个指针是否能转换时,用RTTI可以知道当前实际对象,然后遍历自己所有的父类,看是否有与目标类型一致的,如果有就可以进行转换。
3) dynamic_cast是安全的,可以通过检查返回值或异常捕捉来判断是否转成功。其中检查返回值用于指针转换,异常捕捉用于引用转换。
4) 补充一点,与static_cast不同,即使两个类没有直接继承关系,但是只要在一个类层次结构中,就有可能指向同一个对象,也就可以进行dynamic_cast。以下图为例,C继承自A,B。A, B指针就可以进行dynamic_cast,并可能成功。
C * pc = new C;
A* pa = pc;
B* pb = pc;
pb = dynamic_cast(pa); // 可以成功进行转换,因为二者指向的都是C对象。
下面的例子主要是关于RTTI的,打印出一个对象和她所有父类的运行时信息,这里的运行时信息主要是类的名字。
#include
'iostream'#include 'string' #include using namespace std;class Zero{public: virtual void f111() { }};class Base : public Zero{public: virtual void f() { }};class Deri1234567890ve : public Base{};typedef unsigned long DWORD;struct PMD{ int mdisp; //member displacement int pdisp; //vbtable displacement int vdisp; //displacement inside vbtable};struct RTTIBaseClassDescriptor{ struct TypeDescriptor* pTypeDescriptor; //type descriptor of the class DWORD numContainedBases; //number of nested classes following in the Base Class Array struct PMD where; //pointer-to-member displacement info DWORD attributes; //flags, usually 0};struct TypeDescriptor{ DWORD ptrToVTable; DWORD spare; char name[ ];};struct RTTIClassHierarchyDescriptor{ DWORD signature; //always zero? DWORD attributes; //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance DWORD numBaseClasses; //number of classes in pBaseClassArray struct RTTIBaseClassArray* pBaseClassArray;};struct RTTICompleteObjectLocator{ DWORD signature; //always zero ? DWORD offset; //offset of this vtable in the complete class DWORD cdOffset; //constructor displacement offset struct TypeDescriptor* pTypeDescriptor; //TypeDescriptor of the complete class //int * ptr; struct RTTIClassHierarchyDescriptor* pClassDescriptor; //describes inheritance hierarchy};int main(){ /*Base *pderive = new Deri1234567890ve(); int **ptr = (int **)(&pderive); int *ptable = (int *)(*(int *)(*ptr)); int * rtti = ptable -1; RTTICompleteObjectLocator * RIIT_locator = (RTTICompleteObjectLocator *)( *(int*)rtti); coutpTypeDescriptor->name<>*/ Base *pderive = new Deri1234567890ve(); int *ptable = (int*)*(int*)pderive; int * rtti = ptable -1; // 显示当前类的名字“。。Deri1234567890ve。。”
RTTICompleteObjectLocator * RIIT_locator = (RTTICompleteObjectLocator *)( *(int*)rtti); coutpTypeDescriptor->nameendl; // 显示自己和所有父类的名字
int * p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray); int * p2 = (int*)*(p1+2); TypeDescriptor* pDesc = (TypeDescriptor*)(*p2); cout'One of Base Classes: 'nameendl; p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray); p2 = (int*)*(p1 + 1); pDesc = (TypeDescriptor*)(*p2); cout'One of Base Classes: 'nameendl; p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray); p2 = (int*)*(p1); pDesc = (TypeDescriptor*)(*p2); cout'One of Base Classes: 'nameendl;}
参考:
浅议 Dynamic_cast 和 RTTI http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html
http://www.openrce.org/articles/full_view/23
asdfasdf
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。