programacion ejemplo copia c++ c++11

copia - destructor c++ ejemplo



¿Por qué no se copia mi objeto cuando se elimina el constructor de mover? (1)

Los miembros eliminados del movimiento son malvados. No están prohibidos, porque algún día, alguien encontrará un uso inteligente para ellos. Pero no he visto un buen uso todavía.

Eliminar un miembro especial no es lo mismo que no tener un miembro especial. En ninguna parte es esto más obvio que con el constructor de movimientos y el operador de asignación de movimientos.

Cuando está presente, ya sea eliminado, predeterminado o definido por el usuario, el constructor de movimientos y el operador de asignación de movimientos participan en la resolución de sobrecarga. Eso significa que "compiten" con los miembros de la copia especial. Los miembros de la copia normalmente favorecerán los valores constantes, mientras que los miembros de movimiento atraerán valores.

Cuando se devuelve un tipo local desde una función (cuando el tipo local es el mismo tipo no cv calificado que el tipo de retorno), la declaración de retorno primero considera la expresión de retorno como un valor r, y solo si no puede encontrar un constructor, entonces será considerado como un lvalor. Es decir, la coincidencia con el constructor adecuado para devolver un objeto local desde una función es una operación de 2 fases.

Cuando no tiene un constructor de movimiento (ni siquiera se elimina), pero tiene un constructor de copia normal (toma una constante &), entonces el valor de r de la declaración de retorno coincidirá con el constructor de copia.

Cuando tiene un constructor de movimiento, incluso si está marcado como borrado, el valor de la declaración de retorno encontrará al constructor de movimiento una mejor coincidencia que el constructor de copia.

Resumen

A menos que realmente sepa lo que está haciendo, nunca elimine los miembros del movimiento. Si no desea que su tipo sea móvil, simplemente no defina los miembros de movimiento y asegúrese de declarar miembros de copia, incluso si los miembros de copia son =default ''d.

Actualizar

Supongo que es difícil proporcionar citas del Estándar sobre lo que no hace la eliminación. - DyP

8.4.3 Definiciones eliminadas [dcl.fct.def.delete]

2 Un programa que hace referencia a una función eliminada de manera implícita o explícita, que no sea para declararla, está mal formado. [Nota: Esto incluye llamar a la función implícita o explícitamente y formar un puntero o puntero a miembro a la función. Se aplica incluso para referencias en expresiones que no son potencialmente evaluadas. Si una función está sobrecargada, se hace referencia solo si la función se selecciona por resolución de sobrecarga. - nota final]

Actualización 2

12.8 Copiar y mover objetos de clase [class.copy]

9 Si la definición de una clase X no declara explícitamente un constructor de movimiento, uno se declarará implícitamente como predeterminado si y solo si

  • X no tiene un constructor de copia declarado por el usuario,
  • X no tiene un operador de asignación de copia declarado por el usuario,
  • X no tiene un operador de asignación de movimiento declarado por el usuario, y
  • X no tiene un destructor declarado por el usuario.

[Nota: cuando el constructor de movimiento no se declara implícitamente o no se proporciona explícitamente, las expresiones que de otro modo habrían invocado al constructor de movimiento pueden invocar un constructor de copia. - nota final]

Estoy tratando de usar este código para demostrar el uso del constructor de copia. Mi presunción era que cuando tengo una función que devuelve por valor, mi compilador realizará, de forma predeterminada, un movimiento del objeto. Pero cuando el constructor de movimiento no está disponible, el compilador se copiará en su lugar (en C ++ 03, el compilador se copiaría cuando se devuelva por valor). Entonces, ¿por qué en el siguiente ejemplo el compilador intenta llamar al constructor de movimiento eliminado explícitamente en lugar del constructor de copia disponible? Estoy compilando esto en GCC 4.7.2.

struct S { S() = default; S(S const &) = default; S(S&&) = delete; }; S f() { return S{}; } int main() { f(); }

prog.cpp: En la función ''S f()'' :
prog.cpp: 8: 18: error: uso de la función eliminada ''S::S(S&&)''
prog.cpp: 5: 5: error: declarado aquí