提问者:小点点

成员缺省构造函数的必要性


我被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

共1个答案

匿名用户

在B的构造函数中是否有一些对A的默认构造函数的隐式调用,而我缺少了这些调用?

是的。从引用中

在构成构造函数的函数体的复合语句开始执行之前,所有直接基、虚拟基和非静态数据成员的初始化都已完成。

(重点是地雷)

所以在构造函数中

B()   {
 // ^ here

在开大括号之前,初始化成员_a。但是由于没有默认的构造函数,您会得到一个错误。您可以通过显式初始化它来避免这种情况

B() : _a(42) {