问题
I have a specific situation where I've got an object that I want to use the boost random number generators on, and it has lead to a greater question which I cannot seem to answer. Here is the example code of what I'm trying to produce.
First, my header:
Class MyObject {
protected:
double some variable;
boost::random::mt19937 rgenerator;
boost::uniform_real<double> dist_0_1;
boost::variate_generator< boost::mt19937&, boost::uniform_real<double> > rand01
}
Now what I want to do is:
Class MyObject {
protected:
double some variable;
boost::random::mt19937 rgenerator(std::time(0)); //initialize to a "random" seed
boost::uniform_real<double> dist_0_1(0,1); //set the distribution to 0-1
boost::variate_generator< boost::mt19937&, boost::uniform_real<double> > rand01(rgenerator, dist_0_1);//tell it to use the above two objects
}
But this doesn't work because it is in a header. I thought I could use the constructor of MyObject to somehow call the constructors on the various sub-objects (distribution, generator, but I can't figure out how. By the time the constructor of MyObject is called, the sub-objects' default constructors have already been called, and I haven't found that they have member methods to reset these properties... besides which, that isn't the point where I am confused. Now maybe there are too many things going on and I'm confusing issues, but as far as I can tell, my problem reduces to this following, childish example:
Class Tree {
Tree();
Tree(int);
protected:
fruit apples(int);
}
Tree::Tree() {
apples(0); //won't work because we can't call the constructor again?
}
Tree::Tree(int fruit_num) {
apples(fruit_num); //won't work because we can't call the constructor again?
}
Class Fruit {
public:
Fruit();
Fruit(int);
protected:
int number_of_fruit;
}
Fruit::Fruit() {
number_of_fruit = 0;
}
Fruit::Fruit(int number) {
number_of_fruit = number;
}
I'm sure this is second nature to everyone else out there, but I can't find an article that talks about the best practice for initializing member objects of an object to a non-default constructor value.
回答1:
What you want is an initializer list. For example:
Tree::Tree(int fruit_num)
: apples(fruit_num) // Initializes "apple" with "fruit_num"
{
}
You simply add a colon (:
) after the constructor parameters and before the opening brace {
. You can separate different member constructors with commas (,
). Example:
Tree::Tree(int fruit1, int fruit2) : apples(fruit1), bananas(fruit2) {
}
回答2:
The answer to this question is relatively straightforwards. You use initializer lists.
Here's an example:
class MyClass {
private:
SomeOtherType sot;
public:
MyClass() : sot(parametersForConstructorOfSOT) {}
};
You can extend this to multiple member objects, of course; it can also be used to call the constructor of a parent class to initialize private entries in a parent class if you need to do something like that.
回答3:
You're so close! Just use the initialiser list syntax:
Tree::Tree() : apples(0) {
// ...
}
Tree::Tree(int fruit_num) : apples(fruit_num) {
// ...
}
来源:https://stackoverflow.com/questions/7507526/initializing-a-member-class-of-an-object-using-a-non-default-constructor-in-c