如何在不使用复制构造函数的情况下初始化类成员

4
我现在正在编写C++代码进行数学计算。然而,似乎不可能使用普通构造函数来初始化类成员。
为了实例化,首先调用A的构造函数。到那时,p和q只是声明,因此p和q也没有被实例化。因此,我应该能够调用B的构造函数来实例化它们。对吗?我认为我的C++类理解可能有误,所以在这里发帖确认。
class B{
    // default constructor and copy constructor
}

class A{
private:
    B p;
    B q;
public:
    explicit A(int _p, int _q);
}

// implementation
A::A(int _p, int _q){
    // some computing goes here so I can't apply 
    // A::A(int _p, int _q):p{_p}, q{_q}

    // p = B{_p}
    // q = B{_q} 
    // this works

    p{_p}; // Can't compile.
    q{_q}; // What's wrong with this?
}
2个回答

4

不,构造函数的行为实际上是这样的:


A::A(/* parameters */)
    : /* member constructors called here, explicitly or by default, in order of declaration */
{
     /* your constructor code */
}

换句话说,当您进入构造函数体时,所有类成员都已完全构建,如果它们在初始化列表中指定,则从初始化列表中构建,否则默认构建。因此,您的 A 构造函数的行为就像您编写了 A::A(int _p, int _q) : p{}, q{} { /* code */ }q = B{_q}; 不会调用拷贝构造函数; 它会构造一个临时的 B 对象,并调用 q 的复制或移动赋值运算符,但由于编译器在许多情况下会为您生成这些运算符,因此可以编译。 q{_q}; 作为一条语句,在 C++ 中根本无效。

1
问题在于你不能使用初始化列表按照你尝试的方式进行赋值。而且,由于你无法一开始就初始化变量,实际上你是在寻找一种赋值方法(请注意,p和q已经被默认初始化)。当你写下以下代码时:
p{_p};
q{_q};

这只是无效的语法,因为在变量已经被初始化后(在构造函数的初始化列表/变量声明之外的任何地方),没有定义过的操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接