Tuntenfisch Tuntenfisch - 7 days ago 5
C++ Question

Why does the behavior of non-virtual methods (when called from derived classes) change if the base class has an/no additional virtual method(s)?

Given is the following code:

#include <iostream>
#include <typeinfo>

using namespace std;

class A
{
public:
void print1()
{
cout << typeid(*this).name() << endl;
}

virtual void print2()
{
cout << typeid(*this).name() << endl;
}
};

class B : public A {};

int main()
{
B b;

b.print1();
b.print2();

return 0;
}


I expected the output to be:

class A
class B


But the output is actually:

class B
class B


If I remove the virtual specifier from the second function the output is as expected:

class A
class A


As far as I know, virtual member functions allow dynamic binding so the type of an object can be determined dynamically. Non virtual member functions do not allow dynamic binding, correct?

The member function print2() in the code above is virtual so that's why typeid(*this).name() returns "class B" instead of "class A" when called from class B.

The member function print1() is not virtual but still returns "class B" when called from class B only because there's another member function in class A that is virtual which is print2() in this case.

Since the member function print1() doesn't have a virtual specifier, shouldn't the result always be "class A", regardless from where it's called? Why is this not the case?

Answer

typeid, when applied to something of polymorphic class type (which is the fancy name for "classes with at least one virtual function), always returns the dynamic type. The context of the use doesn't matter.

In other words, in this case, typeid itself behaves like a virtual function.