在 C++ 中使用非默认构造函数初始化对象的成员类

Posted

技术标签:

【中文标题】在 C++ 中使用非默认构造函数初始化对象的成员类【英文标题】:Initializing a member class of an object using a non-default constructor in C++ 【发布时间】:2011-09-21 22:33:29 【问题描述】:

我有一个特定的情况,我有一个对象,我想在其上使用 boost 随机数生成器,这导致了一个更大的问题,我似乎无法回答。这是我正在尝试生成的示例代码。

首先,我的标题:

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

现在我想做的是:

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

但这不起作用,因为它在标题中。我以为我可以使用 MyObject 的构造函数以某种方式调用各种子对象(分布、生成器)的构造函数,但我不知道如何。当调用 MyObject 的构造函数时,子对象的默认值构造函数已经被调用,我还没有发现他们有成员方法来重置这些属性......除此之外,这不是我感到困惑的地方。现在可能有太多事情发生了,我m 令人困惑的问题,但据我所知,我的问题归结为以下这个幼稚的例子:

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;


我确信这是其他所有人的第二天性,但我找不到一篇文章讨论将对象的成员对象初始化为非默认构造函数值的最佳实践。

【问题讨论】:

【参考方案1】:

你想要的是一个初始化列表。例如:

Tree::Tree(int fruit_num) 
    : apples(fruit_num) // Initializes "apple" with "fruit_num"


您只需在构造函数参数之后和左大括号 之前添加一个冒号 (:)。您可以使用逗号 (,) 分隔不同的成员构造函数。示例:

Tree::Tree(int fruit1, int fruit2) : apples(fruit1), bananas(fruit2) 

【讨论】:

+1 用于解释其他可能性。为了完整起见,您还可以指定基类的名称(使用非默认基类构造函数),或(在 C++11 中)当前类的名称(使用构造函数委托)。 感谢所有建议初始化列表的人。这就是问题所在。我见过它们使用过,但只是微不足道的……所以我从来没有了解过它们的实际用途!他们解决了问题!【参考方案2】:

这个问题的答案相对简单。您使用初始化列表。

这是一个例子:

class MyClass 
private:
     SomeOtherType sot;
public:
    MyClass() : sot(parametersForConstructorOfSOT) 
;

当然,您可以将其扩展到多个成员对象;如果你需要做类似的事情,它也可以用来调用父类的构造函数来初始化父类中的私有条目。

【讨论】:

【参考方案3】:

你离得太近了!只需使用初始化列表语法:

Tree::Tree() : apples(0) 
    // ...


Tree::Tree(int fruit_num) : apples(fruit_num) 
    // ...

【讨论】:

以上是关于在 C++ 中使用非默认构造函数初始化对象的成员类的主要内容,如果未能解决你的问题,请参考以下文章

[ C++ ] 类与对象(下) 初始化列表,友元,static成员,内部类

C++从入门到入土第四篇:类与对象(中篇)

C++调用父类的构造函数规则

C++中,类内的成员变量自动初始化为零吗,而全局变量随意赋值

C++中如何在子类的构造函数中调用基类的构造函数来初始化基类成员变量

C++知识分享:C++类特殊成员函数