1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
Although constructors of polymorphic classes may (indirectlly) call virtual
members, that's probably not what you want as constructors of polymorphic
classes don't consider that those members may be overridden by derived
classes. As an opening example: if the class tt(Vehicle) would
define these members:
verb( public:
void Vehicle::prepare()
{
vPrepare();
}
private:
virtual void Vehicle::vPrepare()
{
cout << "Preparing the Vehicle\n";
})
and tt(Car) would override tt(vPrepare):
verb( virtual void Car::vPrepare()
{
cout << "Preparing the Car\n";
})
then tt(Preparing the Car) would be shown by the following code fragment:
verb(Car car{1200};
Vehicle &veh = car;
veh.prepare();)
Maybe a preparation is always required. So why not do it in the base
class's constructor? Thus, the tt(Vehicle's) constructor could be defined as:
verb( Vehicle::Vehicle()
{
prepare();
})
However, the following code fragment shows tt(Preparing the Vehicle),
and em(not) tt(Preparing the Car):
verb(Car car{1200};)
As base classes' constructors do not recognize overridden virtual members
tt(Vehicle's) constructor simply calls its own tt(vPrepare) member instead of
tt(Vehicle::vPrepare).
There is clear logic to base class constructors not recognizing overridden
member functions: polymorphism allows us to tailor the base class's interface
to derived classes. Virtual members exist to realize this tailoring process.
But that's completely different from not being able to call derived classes'
members from base classes' constructors: at that point the derived class
objects haven't yet properly been initialized. When derived class objects are
constructed their base class parts are constructed before the derived class
objects themselves are in a valid state. Therefore, em(if) a base class
constructor would be allowed to call an overridden virtual member then that
member would most likely use data of the derived class, which at that point
haven't properly been initialized yet (often resulting in undefined behavior
like segmentation faults).
|