конструктор перемещения

Автор еще сам до конца не постиг глубину конструктора перемещения. Но тем не менее начинаем разбираться в причинах. Похоже, что до стандарта С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()

Примечание: конструктор по умолчанию (обычный) нужен явно определенный в коде класса.