为什么对象可以 "moved" 甚至缺少移动构造函数和移动赋值运算符?

Why object could be "moved" even lacks move constructor and move assignment operator?

http://en.cppreference.com/w/cpp/language/rule_of_three

几个月前我开始使用 c++11 并且看过五人法则。

所以..我开始将复制constructor/copy赋值operator/moveconstructor/move赋值运算符和默认关键字放在每个class具有虚拟析构函数的

因为规则告诉我,如果您声明显式析构函数,那么您的 class 将不再具有其隐式移动构造函数和移动赋值运算符。

所以我认为 gcc 会向我抱怨 class 由于缺少移动构造函数和移动赋值运算符。

但是效果很好!发生什么事了??

class Interface {
public:
    virtual ~Interface() = default;  // implicit destructor
};

class ImplA : public Interface {
public:
    virtual ~ImplA() = default; // implicit destructor
};

ImplA first;
ImplA second(first);            // copy constructor, OK. understood it.
ImplA third(std::move(first));  // move constructor, it's OK. Why?
second = first;             // copy assignment, OK. understood it.
second = std::move(first);  // move assignment, it's also OK. Why?

So I think gcc is going to complain to me that below class due to lack of move constructor and move assignment operator.

因为可以通过复制构造函数和复制赋值运算符执行所需的操作。 Interface 仍然有复制构造函数和复制赋值运算符,它们是 implcitly declared。右值总是可以绑定到 const Interface&.

更准确地说,即使没有提供移动构造函数和移动赋值运算符,Interface 仍然是 MoveConstructible

A class does not have to implement a move constructor to satisfy this type requirement: a copy constructor that takes a const T& argument can bind rvalue expressions.

MoveAssignable.

The type does not have to implement move assignment operator in order to satisfy this type requirement: a copy assignment operator that takes its parameter by value or as a const Type&, will bind to rvalue argument.


顺便说一句:如果您显式地创建移动构造函数和移动赋值运算符 delete,那么复制和移动操作都会失败。与右值表达式一起使用,将选择显式删除的重载,然后失败。使用左值表达式也会失败,因为由于移动构造函数或移动赋值运算符的声明,复制构造函数和复制赋值运算符被隐式声明为已删除。