I have the following class called Tree, which has a member object of class Leaf. Leaf requires a parameter from Tree (height_) for its construction. I can write an intialize method for this. But do we know the order in which constructors are called, so that dependencies in the construction of member objects are met when the Tree class is constructed? In other words, when there is dependency in the instantiation of a member object, is an separate initialization method (for the member object) the only way to go? A minimal code below, I have put a question mark in the argument to the constructor of Leaf to indicate my question:
class Tree {
private:
float height_;
Leaf leaf_(?);
public:
explicit Leaf(const std::istream& input);
};
void Tree::Tree(const std::istream& input){
// read height_ from input
...
}
class Leaf {
private:
float height_fraction_;
public:
// height is required for construction of Leaf class
Leaf(const float& height);
};
void Leaf::Leaf(const float& height)
{
height_fraction_ = 0.5*height;
}
CodePudding user response:
Construction of the members happens in the order in which they are declared. This is very important for the following. If the order of declaration does not match the order in which the dependencies are used, then the program will have undefined behavior.
The initializers with which they are constructed can be specified in the member initializer list of the constructor after after a colon before the function body:
void Tree::Tree(const std::istream& input)
: height_(/* initializer for height_ */),
leaf_(/* initializer for leaf_ */)
{
//...
}
(Instead of parentheses, braces for list-initialization may also be used.)
In the initializer for leaf_
, the value of height_
can be used.
Since you probably need to do some work to get height_
from the inputs, you probably want to write an extra function for that and call it for /* initializer for height_ */
.