zoukankan      html  css  js  c++  java
  • 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
    ");
        }
    };
    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 !

  • 相关阅读:
    python框架之Flask(4)-上下文管理
    python框架之Flask(3)-Blueprint(蓝图)
    python框架之Flask(2)-路由和视图&Session
    python框架之Flask(1)-Flask初使用
    python中使用redis
    python之以字符串形式导入模块
    学习进度
    学习进度
    毕设进度
    毕设进度
  • 原文地址:https://www.cnblogs.com/xylc/p/3508816.html
Copyright © 2011-2022 走看看