Consider the program:
#include<iostream>
#include<vector>
struct A
{
int a;
A(int) { }
virtual int foo(){ std::cout << "base" << std::endl; return 5; }
};
struct B : A
{
int b;
B(): b(9), A(foo()) { }
virtual int foo(){ std::cout << "derived" << std::endl; return 6; }
};
B b; //prints derived
int main(){ }
DEMO
What Scott Meyers in his Effective C++ said about that was :
During base class construction of a derived class object, the type of the object is that of the base class.
So, I expected base to be printed instead, because we was under the base class class construction while invoking the foo function. What did I miss? Maybe it's UB? If so, please point me out to the relevant section.
Scott means that while you are in the base class constructor usual rules for virtual function don't work. So if you are in the base class constructor then any virtual functions(of that base class) called inside the ctor will be called on the object which is currently under construction in this very ctor.
So your code prints correct result: foo() is called in the B's ctor not in the parent constructor. If you called foo inside the A ctor you would have base printed.
Still the behavior is deemed undefined according to the standard:
[12.6.2/13] Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_-cast (5.2.7). However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the resultof the operation is undefined.
But you should understand that "undefined" here means that you might use some internal state in the called function. Since you don't the behavior will be consistent but standard still deems it undefined. The "undefined" part have nothing to do with what is printed but rather with what might be accessed in the member function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With