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 <iostream>
#include <typeinfo>
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.