2016-09-02 71 views
17

我想实现一个没有复制构造函数的类的移动构造函数。我得到一个错误,该类的成员的默认构造函数丢失。为什么移动构造函数需要其成员的默认构造函数?

这里有一个简单的例子来说明这一点:

struct A { 
public: 
     A() = delete; 
     A(A const&) = delete; 
     A(A &&a) {} 
}; 

struct B { 
     A a; 
     B() = delete; 
     B(B const&) = delete; 
     B(B &&b) {} 
}; 

尝试编译,我得到:

move_without_default.cc: In constructor ‘B::B(B&&)’: 
move_without_default.cc:15:11: error: use of deleted function ‘A::A()’ 
    B(B &&b) {} 
     ^
move_without_default.cc:6:2: note: declared here 
    A() = delete; 
^

为什么这是一个错误?任何方式呢?

+8

用'= default'替换'{}';' – cpplearner

+0

因为'A'的默认构造函数被删除,但'B'使用它。 – tkausl

+6

空移动构造函数不会自动尝试执行逐个成员的移动。你的移动构造函数试图默认构造'a',而不是移动 - 构造它。 – user2357112

回答

17

使用构造函数的初始值设定项列表初始化A成员。按照书面的说法,移动构造函数使用(如编译器所说的)A的默认构造函数。

B(B&& b) : a(std::move(b.a)) {} 
9

移动构造函数通常不需要提供默认的初始化。 您的移动构造函数确实。

移动构造函数仍然是一个构造函数。因此,它必须初始化所有子对象。如果你没有提供显式初始化,那么它会尝试默认初始化它们。如果它不能这样做,你会得到一个错误。

因此,您可以初始化它们(可能从b移动),也可以将= default用于移动构造函数,并让编译器完成它的工作。

23

为什么移动构造函数需要其成员的默认构造函数?

此举构造您定义默认构造一个成员。如果您默认构造任何成员,那么这些成员需要缺省构造函数。

构造函数(无论是常规,复制还是移动)默认初始化未在成员初始化列表中列出的成员,也不具有默认成员初始化。 B::a不在移动构造函数的成员初始化列表中(它根本没有初始化列表),并且没有默认成员初始化。

任何方式吗?

最简单,使用默认的移动构造函数:

B(B&&) = default; 

默认转移构造布展构建成员。

相关问题