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(){ }
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 theB
's ctor not in the parent constructor. If you calledfoo
inside theA
ctor you would havebase
printed.Still the behavior is deemed undefined according to the standard:
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.