I would like to initialize a member variable of a Derived class, and after that pass it to the Base class constructor. I came up with the solution below (also here: http://cpp.sh/4uu4q)
1) Does the following code have a defined or an undefined behavior (UB) ?
2) Is what I am attempting to do an indication of a bad design?
struct Data {
int fValue;
Data( int value = -1 ) : fValue( value )
{}
};
struct Base {
Base( const std::unique_ptr<Data> & derivedData ) {
std::cout << "Constructing Base derivedData=" << derivedData->fValue << std::endl;
}
};
struct Derived : public Base {
std::unique_ptr<Data> fData = std::move( fData );
Derived() : Base( ConstructData() )
{}
const std::unique_ptr<Data> & ConstructData() {
fData.release();
fData.reset( new Data(777) );
std::cout << "in ConstructData: fData->fValue =" << fData->fValue << std::endl;
return fData;
}
};
int main() {
Derived d;
std::cout << "In main: d.fData->fValue =" << d.fData->fValue << std::endl;
return 0;
}
I would like to initialize a member variable of a Derived class, and after that pass it to the Base class constructor.
In C++, the order of construction is of the base part(s) before the derived parts. This is because it is far more common for the derived parts to (potentially) be constructed in terms of the base parts. In order to make this well-defined, the base-then-derived order is specified. Using derived in the base is undefined, therefore.
If you want your base to use derived members, there's a way to ensure the order is OK. Make the "members" base classes too. Note that boost::base_from_member
is built exactly for making this more convenient.
Say you have some
class member_type{};
And you'd like to have derived
have a member_type
member, and derive from base
. Then you could use:
class derived :
private boost::base_from_member<member_type>,
public base {
using my_member_type = private boost::base_from_member<member_type>;
public:
derived();
};
Note that now derived
subclasses both my_member_type
and base
(in that order). Hence, the latter can use the former in its construction.
derived::derived() :
my_member_type{3},
base{my_member_type::member} {
}
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