【问题标题】:Constructing an object within an object在对象中构造对象
【发布时间】:2019-09-12 04:52:36
【问题描述】:

我在类中声明了一个对象A,我想在初始化对象B时初始化对象A:

class A{
    private:
        int num1;
        string word;
    public:
        A(int,word);
};

A::A(int _num1, string _word){
    num1 = num1;
    word = _word;
}

class B{
    private:
        char letter;
        A a;
    public:
        B(char,int,string)
};

B::B(char _letter, int _num1, string _word){
    letter = _letter;
    a(_num1, _word);
}

这给出了错误:只能调用一个函数。 我的问题是,如何在另一个对象中拥有一个可以由外部对象构造函数初始化的对象。

【问题讨论】:

    标签: c++ object constructor


    【解决方案1】:

    你应该用member initializer list初始化数据成员a

    B::B(char _letter, int _num1, string _word) : a(_num1, _word) {
        letter = _letter;
    }
    

    或更好

    B::B(char _letter, int _num1, string _word) : letter(_letter), a(_num1, _word) {}
    

    注意当进入B的构造函数体时,a必须已经被初始化。如果不使用上面的成员初始化器列表,a 将尝试使用默认构造函数进行初始化,但 A 没有。而a(_num1, _word); 只是试图调用a,就好像它是一个函子,但a 不是。

    【讨论】:

      【解决方案2】:

      Member initializer lists 仅用于此目的。它们用于调用成员的构造函数,而不是分配它们。如果默认构造然后分配比直接构造慢,这可能会快很多。几乎在所有情况下都应该使用它们而不是赋值。使用它们来初始化基元并没有性能优势(在这种情况下这只是风格问题,所以我通常还是这样做)。

      这就是使用成员初始化器列表编写构造函数的方式。

      B::B(char _letter, int _num1, string _word)
          : letter(_letter), a(_num1, _word) {}
      

      这可以稍微改进。我们可以为参数赋予与成员相同的名称。在这种情况下,编译器将做“正确的事情”并使用参数初始化成员。这也避免了以下划线 which is a separate issue 开头的标识符。

      B::B(char letter, int num1, string word)
          : letter(letter), a(num1, word) {}
      

      关于成员初始化器列表需要注意的一点是初始化的顺序。成员将按照它们在类中声明的顺序进行初始化。在这种情况下,letter 将在 a 之前初始化。 初始化列表的顺序对初始化顺序没有影响。考虑这个例子:

      B::B(char letter, int num1, string word)
          : a(num1, word), letter(letter) {}
      

      这将初始化letter 然后a。这就是为什么您应该确保顺序与类中声明的顺序相同。如果您将适当的警告标志传递给编译器,它会告诉您这一点,您的 IDE 甚至可能会为您重新排序。

      【讨论】:

        猜你喜欢
        • 2017-02-22
        • 1970-01-01
        • 2020-05-24
        • 2017-04-12
        • 1970-01-01
        • 2010-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多