我被C++14的编译器错误弄糊涂了。它涉及成员变量的缺省构造函数的必要性。在下面的代码中,类A没有默认构造函数。类B有一个由它移动分配的类型a的成员。编译器抱怨缺少的默认构造函数,即使我没有显式地调用它。在B的构造函数中是否有一些对A的默认构造函数的隐式调用,而我缺少了这些调用?我的理解是,如果您在B的构造函数中初始化B的成员,那么默认构造函数就不是必需的。
当B被注释掉时,main中的代码工作得很好。在B的构造函数中本质上相同的东西不起作用。
谢谢,
#include <utility>
class A {
public:
A(int x) : _x{x} {}
A(A &&other) : _x{other._x} {}
A &operator=(A &&other) { _x = other._x; }
private:
int _x;
};
class B {
public:
B() {
A a(2);
_a = std::move(a);
}
private:
A _a;
};
int main() {
A b(1);
A a = std::move(b);
return 0;
}
~/move.cpp: In constructor ‘B::B()’:
~/move.cpp:17:7: error: no matching function for call to ‘A::A()’
B() {
^
~/move.cpp:7:3: note: candidate: A::A(A&&)
A(A &&other) : _x{other._x} {}
^
~/move.cpp:7:3: note: candidate expects 1 argument, 0 provided
~/move.cpp:5:3: note: candidate: A::A(int)
A(int x) : _x{x} {}
^
~/move.cpp:5:3: note: candidate expects 1 argument, 0 provided
在B的构造函数中是否有一些对A的默认构造函数的隐式调用,而我缺少了这些调用?
是的。从引用中
在构成构造函数的函数体的复合语句开始执行之前,所有直接基、虚拟基和非静态数据成员的初始化都已完成。
(重点是地雷)
所以在构造函数中
B() {
// ^ here
在开大括号之前,初始化成员_a
。但是由于没有默认的构造函数,您会得到一个错误。您可以通过显式初始化它来避免这种情况
B() : _a(42) {