先看下方的代码,我们所处的context在<<< void* pX = (void*)pGiven; >>>处,只知道上面这些类的信息和pX指针,怎么判断pX指向对象的类型?
#include <stdio.h> #include <typeinfo> class CBase { public: virtual void message() { printf("hello , this is base "); } }; class CContainerA : public CBase { public: virtual void message() { printf("hello , this is A "); } }; class CContainerB : public CBase { public: virtual void message() { printf("hello , this is B "); } }; class CContainerC { public: virtual void message() { printf("hello , this is %s ",typeid(*this).name()); } }; int main(int argc,char* argv[]) { CContainerA* pGiven = new CContainerA(); void* pX = (void*)pGiven; //pX maybe is a CContainerA* , or a CContainerB* , or a CContainerC* //how to judge it ? CBase* pUnknown = (CBase*)pX; CContainerA* pMaybeA = dynamic_cast<CContainerA*>(pUnknown); CContainerB* pMaybeB = dynamic_cast<CContainerB*>(pUnknown); CContainerC* pMaybeC = dynamic_cast<CContainerC*>(pUnknown);
if(pMaybeA) pMaybeA->message(); if(pMaybeB) pMaybeB->message(); if(pMaybeC) pMaybeC->message();
return 0; }
CContainerA,CContainerB有共同的基类,可以通过强制转换pX到pUnknown,然后dynamic_cast确定是CContainerA还是CContainerB,CContianerC则无法判断。
当然如果是特定编译器,则仍然可判断出pX的对象类型,参照:
http://www.openrce.org/articles/full_view/23
http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html
类的RTTI信息地址保存在虚函数表的-1项。
ADD:
RTTI要求编译器的支持,微软的一些系统dll中没有启用RTTI(vc++ configure : c/c++ - language - enable runtime typeinfo = false),所以会产生下列情况:
void* lpOwner = GetDevice(); IUnknown* pUnknown = (IUnknown*)(lpOwner); IDirect3DDevice9* pDevice = dynamic_cast<IDirect3DDevice9*>(pUnknown); IDirect3DSwapChain9* pSwapChain = dynamic_cast<IDirect3DSwapChain9*>(pUnknown); //Result : pDevice == NULL && pSwapChain == NULL
但是微软有更好的办法:
IUnknown* pUnknown = (IUnknown*)(lpOwner);
IDirect3DDevice9* pDevice = NULL; pUnknown->QueryInterface(IID_IDirect3DDevice9,(void**)&pDevice);
IDirect3DSwapChain9* pSwapChain = NULL; pUnknown->QueryInterface(IID_IDirect3DSwapChain9,(void**)&pSwapChain);
assert(!(pDevice && pSwapChain));
com接口自带RTTI !