If you call a virtual function from a base class then you will call the function in the base class because the vtable is filled in as the class hierarchy is constructed and that is constructed from base class to derived class.
This code demonstrates that
-
-
#include<iostream>
-
using namespace std;
-
-
-
class Base
-
{
-
public:
-
Base()
-
{
-
print();
-
}
-
-
~Base()
-
{
-
}
-
-
virtual void print()
-
{
-
cout << "Base : " << name() << endl;
-
}
-
-
virtual const char *name()
-
{
-
return "Base";
-
}
-
};
-
-
class Derived : public Base
-
{
-
public:
-
Derived()
-
{
-
print();
-
}
-
-
~Derived()
-
{
-
}
-
-
virtual void print()
-
{
-
cout << "Derived : " << name() << endl;
-
}
-
};
-
-
class MoreDerived : public Derived
-
{
-
public:
-
MoreDerived()
-
{
-
print();
-
}
-
-
~MoreDerived()
-
{
-
}
-
-
virtual void print()
-
{
-
cout << "MoreDerived : " << name() << endl;
-
}
-
-
virtual const char *name()
-
{
-
return "MoreDerived";
-
}
-
};
-
-
-
int main()
-
{
-
MoreDerived md;
-
return 0;
-
}
-
showing that as MoreDerived goes though the stages of constructing Base then Derived then MoreDerived caused by the instantiation in main, it calls virtual functions from each of the classes in question as the class is built up from its inherited components giving the output
-
Base : Base
-
Derived : Base
-
MoreDerived : MoreDerived
-
So when calling a virtual function from a base constructor it is using the base classes vtable and calls the base method not the method of the class being constructed.
So this means that if you call a virtual function from a constructor the intended function call may not take place if the class is used as a base for another class.
Worst still if the function is pure virtual in the class calling it then you will dereference a NULL pointer and cause a crash which can be demonstrated by changing Base in my example to
-
class Base
-
{
-
public:
-
Base()
-
{
-
print();
-
}
-
-
~Base()
-
{
-
}
-
-
virtual void print()
-
{
-
cout << "Base : " << name() << endl;
-
}
-
-
virtual const char *name() = 0;
-
};
-
giving the output
-
pure virtual method called
-
terminate called without an active exception
-
Aborted
-
You can never be absolutely sure someone wont derive from your class so ...
For these reasons calling a virtual function from a constructor is considered bad practice and calling one from a destructor is generally worst.
Your compiler may be able to warn you about this and static analysis tools like lint certainly can.