I have two classes, Base
and Derived
. Derived
constructs Base
using its own member object, which inherits from Base::BaseChild
.
struct Base
{
struct BaseChild
{
int x = 5;
};
Base(BaseChild& c): baseData(c), constantVar(c.x)
{
assert(constantVar == 5);
}
int getX() const {return baseData.x;}
private:
const int constantVar;
BaseChild& baseData;
};
struct Derived: public Base
{
struct DerivedChild: public BaseChild
{
double y = 4.0;
};
Derived(): Base(data) {}
private:
DerivedChild data;
};
Derived myObject;
assert(myObject.getX() == 5);
Reasoning: I do this in this way because everything seems pretty encapsulated for my case, where I need to send Childs to swap their content (vector
, shared_ptr
, unique_ptr
) with other Childs, keeping child memory address, and I still can access to Child object from base class without the need of a virtual function, which was killing my app performance.
Question: I've read another post like this one, where it states initialization of a Derived
member before the Base
isn't possible. So the constantVar
assert would always fail. However getX()
works fine, after the constructor, and I'm interested in these functions which are called once the constructor ends. Is this safe? Or is there any hidden danger here?
CodePudding user response:
The base class Base
of Derived
is constructed before the member data
.
As a result data
will not be initialized when you pass a reference to it to Base
's constructor. The initialization will happen after that constructor call.
You are however trying to read the member x
of data
in Base
's constructor. At this point data
's lifetime has not started yet and accessing the value of a non-static data member of an object outside its lifetime causes undefined behavior.
Whether or not the assertions succeed isn't significant. Undefined behavior allows for either outcome.
The situation would be potentially different (although technically not rules in the standard) if you were not trying to access the value of data
inside Base
's constructor, but only storing the reference to it.