Автор еще сам до конца не постиг глубину конструктора перемещения. Но тем не менее начинаем разбираться в причинах. Похоже, что до стандарта С11 в определенных ситуациях получалось избыточное создание и удаление одних и тех же объектов. (rvalue , lvalue)
Особенность конструктора перемещения в том, что работает он только с RValue (ссылками). Что это значит? RValue ссылка получается у нас например, когда в присваивании (после =) в значении справа мы используем результат функции.
Мы знаем, что RValue ссылка это объект, который скопируется в объект слева от оператора = и значем, что RValue будет уничтожена при выходе из функции где она создавалась, поэтому почему бы уйти от полного копирования объекта и не заменить все это переносом только ссылок на внутренние данных исходного объекта.
Например у нас есть функция record() :
class A
{
public:
A() // конструктор по умолчанию обычный
{
qDebug() << "A() this:" << this << " // easy default ctor";
}
~A()
{
qDebug() << "~A " << this;
}
// конструктор перемещения
A (A&& x)
{
qDebug() << "move ctor " << this ;
//x.ptr = nullptr;
}
};
A record() // здесь rValue - это важно
{
A clA;
return clA;
}
void foo() // используем, чтобы отследить деструкторы классов
// при выходе из функции у классов созданных на стеке (то есть не динамически, т.е. без new)
// обязаны будут вызваны деструкторы
{
A clA = record();
qDebug() << "<- foo()";
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "--------main()---------";
qDebug() << "-> foo()";
foo();
qDebug() << "return from foo()";
return a.exec();
}
Вывод консоли говорит, что вызвался конструктор перемещения:
--------main()---------
-> foo()
A() this: 0x115fb37 // easy default ctor
move ctor 0x115fb63
~A 0x115fb37
<- foo()
~A 0x115fb63
return from foo()
Примечание: конструктор по умолчанию (обычный) нужен явно определенный в коде класса.