Inheritance, Constructors, Virtual Methods and typeid
Posted by Kaya Kupferschmidt • Wednesday, May 3. 2006 • Category: C++
When working with inheritance and virtual methods, there might be some surprises when one tries to call a virtual method inside a constructor - and this is the reasons why one should never ever call virtual methods inside a constructor or inside a destructor.
Consider the following simple code
Guess what the output will look like. Some people might expect something like follows:
But unfortunately this turns out to be wrong. You will actually see the following output
This behaviout actually is orrect and makes a lot of sense. Remember that when the constructor A::A() is called, the object actually is still of type A and not of type B yet. The same is true with destructors. When A::~A() is called, the destructor of the derived class B::~B() has already been called, thus the object isn't of type B any more. You can verify this claim by printing the typeids of the classes inside the constructor and dstructor, like follows:
This example will produce the following output:
Thus it is impossible to detect the real class type inside a constructor or detructor.
Consider the following simple code
class A {
public:
A() {
printf("A::A() calls ");
f();
};
~A() {
printf("A::~A() calls ");
f();
};
virtual void f() {
printf("A::f()\n");
};
};
class B : public A {
public:
B() {
printf("B::B() calls ");
f();
};
~B() {
printf("B::~B() calls ");
f();
};
virtual void f() {
printf("B::f()\n");
};
};
void main(void) {
B obj;
obj.f();
};
Guess what the output will look like. Some people might expect something like follows:
A::A() calls B::f()
B::B() calls B::f()
B::~B() calls B::f()
A::~A() calls B::f()
But unfortunately this turns out to be wrong. You will actually see the following output
A::A() calls A::f()
B::B() calls B::f()
B::~B() calls B::f()
A::~A() calls A::f()
This behaviout actually is orrect and makes a lot of sense. Remember that when the constructor A::A() is called, the object actually is still of type A and not of type B yet. The same is true with destructors. When A::~A() is called, the destructor of the derived class B::~B() has already been called, thus the object isn't of type B any more. You can verify this claim by printing the typeids of the classes inside the constructor and dstructor, like follows:
class A {
public:
A() {
printf("A::A() is of type %s\n",
typeid(*this).name());
};
~A() {
printf("A::~A() is of type %s\n",
typeid(*this).name());
};
virtual void f() {
};
};
class B : public A {
public:
B() {
printf("B::B() is of type %s\n",
typeid(*this).name());
};
~B() {
printf("B::B() is of type %s\n",
typeid(*this).name());
};
virtual void f() {
};
};
void main(void) {
B obj;
};
This example will produce the following output:
A::A() is of type class A
B::B() is of type class B
B::~B() is of type class B
A::~A() is of type class A
Thus it is impossible to detect the real class type inside a constructor or detructor.



0 Comments
Add Comment