当类的成员未定义移动操作时,我正在努力理解隐式移动操作:
int main() {
struct A // no move: move = copy
{
A() = default;
A(const A&) {
cout << "A'copy-ctor\n";
};
A& operator=(const A&) {
cout << "A'copy-assign\n";
return *this;
}
};
struct B
{
B() = default;
A a; // does this make B non-moveable?
unique_ptr<int> upi;
// B(B&&) noexcept = default;
// B& operator=(B&&)noexcept = default;
};
A a;
A a2 = std::move(a); // ok use copy ctor instead of move one
a2 = std::move(a); // ok use copy assignment instead of move one
B b;
B b2 = std::move(b); // why this works?
b = std::move(b2); // and this works?
// b = b2; // error: copy deleted because of non-copyable member upi
cout << "\nDone!\n";
}
所以我看到的是A
是不可移动的类,因为其复制控制操作已定义,因此只能复制它,并且任何尝试移动该类对象的尝试都将使用相应的复制操作。
直到这里,如果我正确,那还可以。但是B
有一个不可复制的对象upi
,它是unique_ptr
,因此复制操作被定义为已删除的函数,因此我们无法复制此类的对象。但是此类具有不可移动的对象a
,因此我认为此类(B
)既不可复制,也不可移动。但是,为什么b2
的初始化和b
的分配工作正常?到底会发生什么?
B b2 = std::move(b); // ok?!
为什么上面的行调用类A
的副本构造函数,并调用B
的move构造函数?
B
中的move操作行的注释,则上面的初始化将不会编译抱怨引用已删除的功能,对于分配也是一样!任何人都可以帮助我,到底会发生什么?在这里发布问题之前,我已经Google搜索并阅读了cppreference和许多网站。
输出:
A'copy-ctor
A'copy-assign
A'copy-ctor
A'copy-assign
Done!
std :: move不会强制复制对象。它只是返回&&-reference(允许编译器使用move ctor / assign运算符)。如果是1,2,则复制对象。在3,4种情况下(我认为),物体被移动了。但是A仍被复制,因为它无法移动。