Checking the object type in C++11

后端 未结 1 1285
离开以前
离开以前 2021-01-05 21:22

I have class B that inherits from A.

class A
{
};

class B : public A
{
};

And I have three objects.

A* a = new A();
A* a2          


        
1条回答
  •  暖寄归人
    2021-01-05 21:48

    Some classes are polymorphic, some are non-polymorphic.

    A polymorphic class has one or more virtual functions (possibly inherited), a non-polymorphic class has zero virtual functions.

    Your A and B are non-polymorphic.

    A polymorphic version of A and B will exhibit the behaviour you want:

    #include 
    #include 
    
    using namespace std;
    
    struct A
    {
        virtual ~A() {}; // add virtual function
    };
    
    class B : public A
    {
    };
    
    A* a = new A();
    A* a2 = new B();
    B* b = new B();
    
    int main()
    {
        cout << (typeid(*a) == typeid(A)) << endl; // -> 1
        cout << (typeid(*a2) == typeid(A)) << endl; // -> 0 <-- CHANGED
        cout << (typeid(*b) == typeid(A)) << endl; // -> 0
    
        cout << (typeid(*a) == typeid(B)) << endl; // -> 0
        cout << (typeid(*a2) == typeid(B)) << endl; // -> 1 <-- CHANGED
        cout << (typeid(*b) == typeid(B)) << endl; // -> 1
    }
    

    Instances of a polymorphic class store the dynamic type of their most derived object at runtime.

    (In your example a2 is of type pointer-to-A, and is pointing at an object of type A, however this object is only a base class subobject of the most dervived object of type B. What you want to get is the type of this most derived object B when querying a2. For this you need a polymorphic class.)

    That is how polymorphic classes support dynamic_cast and typeid of the most derived object (as well as virtual function dispatch).

    Non-polymorphic classes do not have this information, so they can only report the static type known at compile-time. Non-polymorphic classes are more compact and efficient then polymorphic classes. That is why not all C++ classes are polymorphic. The language leaves it up to the programmer to chose the tradeoff between performance and functionality. For example:

    struct X { int x; };
    struct Y : X {};
    struct Z : Y {};
    

    On my system non-polymorphic Z is sizeof(Z) == 4 bytes, same as an int.

    struct X { int x; virtual ~X() {}; };
    struct Y : X {};
    struct Z : Y {};
    

    Now after making Z polymorphic, sizeof(Z) == 16 bytes. So an array of Z is now 300% larger, because each Z instance has to store its type information at runtime.

    0 讨论(0)
提交回复
热议问题