当前位置: 首页 > 知识库问答 >
问题:

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

荆鸿畅
2023-03-14

我被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个答案

燕元明
2023-03-14

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

是的。从引用中

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

(重点是地雷)

所以在构造函数中

B()   {
 // ^ here

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

B() : _a(42) {
 类似资料:
  • 我不断地得到错误: 下面是Spring有问题的类: 我找到的答案都是...若要定义默认构造函数,请执行以下操作。那...就在那里,来自龙目岛的@noargsconstructor,对吗?即使我把它去掉,自己定义,也不会改变什么。 我尝试自己定义这两个构造函数(no args和all args)都没有用,然后添加了@autowired,这导致了一个错误,即没有'string'bean,这让我在这个阶

  • 引用自C Primer 如果我们显式地要求编译器使用生成移动操作,并且编译器无法移动所有成员,那么移动操作将被定义为删除 如果类有一个定义自己的复制构造函数的成员,但不定义移动构造函数,或者如果类有一个不定义自己的复制操作的成员,并且编译器无法合成,则移动构造函数被定义为删除移动构造函数 有些代码似乎违反了这条规则: X没有定义移动构造函数,编译器不能为它合成一个。 根据上述规则,的移动构造函数被

  • 你能详细说明下面的答案是什么意思吗? 您应该能够切换到Java8,而不必在类中实现新方法。

  • 操作步骤: 菜单栏: Code —> Generate —> Constructor 快捷键: Mac: command + N Windows\/Linux: Alt + Insert —> Constructor

  • 我想在我的对象中编写一个实用函数指针,用于调用该对象中的一组其他函数。此实用程序函数指针应使用默认功能初始化,但也可以重写。 这就是我到目前为止所做的: 编译器不喜欢在捕获lambda函数时使用,并针对该行抛出以下错误: E0413-没有来自“lambda[]void()的合适转换函数- C2440“正在初始化”:无法从“游戏状态::”转换为“void(uu cdecl*)(void)” C243

  • 我想用构造函数注入将一个bean列表注入到一个spring bean中。 但是BeanToInject的实现在其他模块中。这些模块可能被关闭。如果applicationcontext中没有BeanToInject的实现,则spring在start上抛出异常,而不是注入空列表。我能做什么?(对我来说,基于设置器和私有财产的自动取舍不是一种选择。)