主要是參考下圖,了解內存布局,然後寫個實例程序就差不多明白了,但是需要熟悉指針轉換。
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<B*>(pa); // 可以成功進行轉換,因為二者指向的都是C對象。

下面的例子主要是關於RTTI的,打印出一個對象和她所有父類的運行時信息,這裡的運行時信息主要是類的名字。
#include "iostream"
#include "string"
#include <typeinfo>
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);
cout<<RIIT_locator->pTypeDescriptor->name<<endl;*/
Base *pderive = new Deri1234567890ve();
int *ptable = (int*)*(int*)pderive;
int * rtti = ptable -1;
// 顯示當前類的名字“。。Deri1234567890ve。。”
RTTICompleteObjectLocator * RIIT_locator = (RTTICompleteObjectLocator *)( *(int*)rtti);
cout<<RIIT_locator->pTypeDescriptor->name<<endl;
// 顯示自己和所有父類的名字
int * p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray);
int * p2 = (int*)*(p1+2);
TypeDescriptor* pDesc = (TypeDescriptor*)(*p2);
cout<<"One of Base Classes: "<<pDesc->name<<endl;
p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray);
p2 = (int*)*(p1 + 1);
pDesc = (TypeDescriptor*)(*p2);
cout<<"One of Base Classes: "<<pDesc->name<<endl;
p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray);
p2 = (int*)*(p1);
pDesc = (TypeDescriptor*)(*p2);
cout<<"One of Base Classes: "<<pDesc->name<<endl;
}
參考:
淺議 Dynamic_cast 和 RTTI http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html
http://www.openrce.org/articles/full_view/23
asdfasdf