What's the point of IsA() in C++?

前端 未结 5 1149
鱼传尺愫
鱼传尺愫 2021-02-10 16:14

I\'m trying to figure out why some code bases use IsA() to determine object polymorphism if in C++ you can already safely upcast and down cast (using dynamic_cast) ?

So

5条回答
  •  心在旅途
    2021-02-10 17:20

    An example of how to find run time type information without RTTI

    MFC uses a function called IsKindOf() for run time type information. The method MFC uses to find type information is somewhat like the example below.

    #define RUNTIME_CLASS(class_name) (class_name::GetThisClass())
    #define RUNTIME_OBJ(class_name) (class##class_name)
    struct RunTimeClass
    {
        string name;
    };
    class base
    {
        static RunTimeClass RUNTIME_OBJ(base); //watch the naming 
    public:
    
        bool IsExactKind(RunTimeClass* pRTclass)
        {
            if(pRTclass == GetRunTimeClass())
            {
                return true;
            }
            return false;
    
        }
    
        static RunTimeClass* GetThisClass()
        {
            return &RUNTIME_OBJ(base);      
        }
    
        virtual RunTimeClass* GetRunTimeClass()
        {
            return &RUNTIME_OBJ(base);
        }
        virtual ~base() = 0;
    };
    
    class derived: public base
    {
        static RunTimeClass RUNTIME_OBJ(derived); //watch the naming
    public:
        RunTimeClass* GetRunTimeClass()
        {
            return &RUNTIME_OBJ(derived);       
        }
    
        static RunTimeClass* GetThisClass()
        {
            return &RUNTIME_OBJ(derived);       
        }
    
    };
    
    class derived2: public derived
    {
        static RunTimeClass RUNTIME_OBJ(derived2); //watch the naming
    public:
        RunTimeClass* GetRunTimeClass()
        {
            return &RUNTIME_OBJ(derived2);      
        }
    
        static RunTimeClass* GetThisClass()
        {
            return &RUNTIME_OBJ(derived2);      
        }
    
    };
    

    In the cpp file

    RunTimeClass base::classbase = {"base"}; //not using the macro RUNTIME_OBJ
    RunTimeClass derived::classderived = {"derived"}; //not using the macro RUNTIME_OBJ
    RunTimeClass derived2::classderived2 = {"derived2"}; //not using the macro RUNTIME_OBJ
    base::~base() {}
    void main()
    {
        derived *ptrDer = new derived();
        bool isder = ptrDer->IsExactKind(RUNTIME_CLASS(derived));
    
        derived2 *ptrDer2 = new derived2();
        isder = ptrDer2->IsExactKind(RUNTIME_CLASS(derived2));
    
        delete ptrDer;
        delete ptrDer2;
    }
    

    Note that this can only find if the object is of the exact class type. To add type information you just need to inherit from base and add a Runtimeclass variable and implement two functions getthisclass(), getruntimeclass(). MFC use CObject as the base class which provides similiar functionality. Also, there are more macros to make your life easier. IsKindOF() function in MFC walk thourgh the entire hierarchy and find out the object "is a" type of class(which is not there in my scaled down version). You can see this is somewhat similiar to RTTI, hence I guess there is no perfomance difference. It is there in MFC because it was there before RTTI.

    So, if there is an IsA() function which perfoms better than RTTI, I would like to see the implementation.

提交回复
热议问题