Movimiento de objeto, constructor de movimiento y operador de asignación de movimiento

1. ¿Qué es el movimiento de objetos?

    El movimiento de objetos consiste en extraer algunos datos útiles de un objeto A que ya no se usa. Al crear un nuevo objeto B, no es necesario reconstruir los datos en el objeto, pero se extraen del objeto A que ya no se usa. Los datos útiles se utilizan al construir el objeto B.

2. Mover constructor

1. ¿Por qué necesita un constructor de movimiento?

    Ya sabemos que hay constructores de copia y operadores de asignación sobrecargados, los cuales pueden completar la copia de datos de objetos, pero cuando los datos de un objeto son muy grandes, el costo será muy alto. Así que ahora C++11 propone un constructor de movimiento, que se usa para resolver este problema.

2. Demostración del constructor de movimientos.

    El siguiente código demuestra el constructor de movimiento:

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() { // 默认构造函数
        cout << "Use MyClass()" << endl;
    }
    MyClass(const MyClass& other) { // 复制构造函数
        cout << "Use MyClass(const MyClass& other)" << endl;
    }
    MyClass& operator=(const MyClass& other) { // 重载赋值运算符
        cout << "Use MyClass& operator=(const MyClass& other)" << endl;
    }
    MyClass(MyClass&& other) { // 移动构造函数
        cout << "Use MyClass(MyClass&& other)" << endl;
    }
    ~MyClass() { // 析构函数
        cout << "MyClass Destoryed" << endl;
    }
};

MyClass getMyClass() {
    MyClass my1;
    return my1;
}

int main() {
    MyClass my1;
    MyClass my2 = my1;
    MyClass my3(std::move(my2));

    return 0;
}

    En la función main(), la primera línea llama al constructor predeterminado, la segunda línea llama al constructor de copia y la tercera línea usa la función std::move, que cambia my2 de un valor l a un valor r, por lo que la llamada es un mover constructor. Este ejemplo es solo una mirada simple al uso del constructor de movimiento. De hecho, el proceso de "mover" debe implementarse en la función.

3. Mover operador de asignación

    El operador de asignación de movimiento es el mismo que el constructor de movimiento. Simplemente cambia el parámetro de función a un valor r basado en el operador de asignación. El siguiente es un ejemplo simple del uso del operador de asignación de movimiento:

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() { // 默认构造函数
        cout << "Use MyClass()" << endl;
    }
    MyClass(const MyClass& other) { // 复制构造函数
        cout << "Use MyClass(const MyClass& other)" << endl;
    }
    MyClass& operator=(const MyClass& other) { // 重载赋值运算符
        cout << "Use MyClass& operator=(const MyClass& other)" << endl;
    }
    MyClass(MyClass&& other) noexcept { // 移动构造函数
        cout << "Use MyClass(MyClass&& other)" << endl;
    }
    MyClass& operator=(MyClass&& other) noexcept { // 移动赋值运算符
        cout << "Use MyClass& operator=(MyClass&& other)" << endl;
    }
    ~MyClass() { // 析构函数
        cout << "MyClass Destoryed" << endl;
    }
};

MyClass getMyClass() {
    MyClass my1;
    return my1;
}

int main() {
    MyClass my1;
    MyClass my2;
    my2 = std::move(my1);

    return 0;
}

 En el código anterior, agregué el símbolo noexcept al final de las funciones del constructor de movimiento y del operador de asignación de movimiento, que también es

C++11 palabras clave recién agregadas, su función es informar al compilador que el constructor de movimiento y el operador de asignación de movimiento no arrojarán ninguna excepción (para mejorar la eficiencia del compilador). Es un hábito, ¡recuérdalo!

4. Operación móvil sintética

    Las operaciones de movimiento sintetizadas significan que, en algunos casos, el compilador sintetiza automáticamente constructores de movimiento y operadores de asignación de movimiento. Para el problema de síntesis, el resumen es el siguiente:

  • Si una clase (MyClass) define su propio constructor de copia, operador de asignación sobrecargado o destructor (uno de estos tres), el compilador no sintetizará un constructor de movimiento ni un operador de asignación de movimiento para él.

  • Si una clase no proporciona un constructor de movimiento y un operador de asignación de movimiento, utilizará automáticamente un constructor de copia y un operador de asignación sobrecargado en su lugar.

  • Si una clase no define ninguno de sus propios constructores de copia, operador de asignación sobrecargado, destructor y todos los miembros no estáticos de la clase se pueden mover, el compilador sintetizará el constructor de movimiento y la operación de asignación de movimiento para el símbolo de clase.

Supongo que te gusta

Origin blog.csdn.net/hu853712064/article/details/130559622
Recomendado
Clasificación