Assume I define a class Foo
, which does not implement a default constructor.
In addition, I have a class Bar
, which "owns" an instance of Foo
:
class Foo() {
private:
int m_member;
public:
Foo( int value ) : m_member(value) { }
};
class Bar() {
private:
Foo m_foo;
public:
Bar( /* ... */ ) {
int something;
/* lots of code to determine 'something' */
/* should initialize m_foo to 'Foo(something)' here */
}
};
The code as shown won't run, since Bar
is trying to call the default constructor of Foo
.
Now what I am trying to do is to have the constructor of Bar
first determine something
and then pass the result to the constructor of Foo
.
One way to solve this is to have Bar
only own a reference/pointer to Foo
and initialize it after m_something
was determined. However, I'd like to avoid that to make clear that the lifetime of m_foo
is completely dependent on the lifetime of the owning class.
Another way would be to implement a default constructor in Foo
and set the value later, which I would also like to avoid, since any instance of Foo
should have a valid value for it's member (at any time).
What is the proper way to implement this? Am I stuck with a reference/pointer here?
To initialize a class member variable, put the initialization code in a static initialization block, as the following section shows. To initialize an instance member variable, put the initialization code in a constructor.
There are two ways to initialize a class object: Using a parenthesized expression list. The compiler calls the constructor of the class using this list as the constructor's argument list. Using a single initialization value and the = operator.
for built-in type, it is initialized to 0. for class type, it is default initialized.
A default constructible class is a class that has a default constructor (either its implicit constructor or a custom defined one). The is_default_constructible class inherits from integral_constant as being either true_type or false_type, depending on whether T is default constructible.
The best idea will be to create helper function, that will calculate something and then just initialize m_foo
in constructor initialized list.
class Bar {
private:
Foo m_foo;
public:
Bar( /* ... */ ) : m_foo(calculate_something()) {
}
private:
static int calculate_something()
{
int something = 0;
// lot of code to calculate something
return something;
}
};
Does this complex initialization code actually belong to Bar
? It may be good to consider having a separate class to just do this initializing. Something like
class Bar {
public:
Bar(int param, Foo foo): m_foo(foo) {
// do just some very simple calculations, or use only constructor initialization list
}
...
}
class BarBuilder {
public:
BarBuilder(/*...*/) {
// do all calculations, boiling down to a few parameters for Bar and Foo
Foo foo(fooParameter);
m_result = new Bar(barParameter, foo); // give Foo here explicitly
}
Bar getResult() { return *m_result; }
private:
Bar* m_result; // or better use unique_ptr
}
This also opens the way to a full Builder pattern that might be useful in case, for example, you do not always need all that complex calculations.
This assumes all classes to be copy-constructible, but you may more-or-less easily modify it to support what you need.
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