我现在正在编写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?
}
答案 0 :(得分:2)
不,构造函数的行为实际上如下所示:
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 :(得分:1)
问题在于,您根本无法使用初始化列表按照您尝试的方式执行分配。而且,由于您最初无法初始化变量,因此您实际上正在寻找分配(请注意p
和q
已经默认初始化)。当你写:
p{_p};
q{_q};
它只是无效的语法,因为在变量已经初始化之后没有在lvalue<initialization_list>
上定义的操作(在构造函数的初始化列表/变量声明之外的任何其他地方)