C++ RTTI的应用

 

先看下方的代码,我们所处的context在<<< void* pX = (void*)pGiven; >>>处,只知道上面这些类的信息和pX指针,怎么判断pX指向对象的类型?

#include <stdio.h>
#include <typeinfo>

class CBase
{
public:
    virtual void message()
    {
        printf("hello , this is base\n");
    }
};
class CContainerA : public CBase
{
public:
    virtual void message()
    {
        printf("hello , this is A\n");
    }
};

class CContainerB : public CBase
{
public:
    virtual void message()
    {
        printf("hello , this is B\n");
    }
};

class CContainerC
{
public:
    virtual void message()
    {
        printf("hello , this is %s\n",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 !

posted @ 2014-01-07 14:39  *神气*  阅读(499)  评论(0编辑  收藏  举报