30

¿El siguiente snipplet es correcto para des-definir todos los métodos y constructores generados para una clase?Uso correcto de `= delete` para métodos en las clases

struct Picture { 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no accidental construction, i.e. temporaries and the like 
    Picture() = delete; 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 

    // no move 
    Picture(Picture&&) = delete; 

    // no move-assign 
    Picture& operator=(Picture&&) = delete; // return type correct? 
}; 

Esto elimina todas las implementaciones del compilador predeterminado y solo abandona el destructor, ¿verdad? Sin eso, la clase sería (casi) inservible, supongo, pero podría eliminarla también, ¿correcto?

¿El tipo de retorno Picture& del movimiento-asigne operator=(Picture&&) correcto? ¿Hace una diferencia si escribí Picture&& para el tipo de devolución?

+3

Parece que C++ realmente ha cambiado mucho en C++ 0x !, algo interesante. – briantyler

+1

es una sintaxis más clara que la práctica común de ocultar esos métodos en una sección 'privada', y solo * declarando * pero no * definiendo * ellos. – towi

Respuesta

26

Además de la respuesta de Xeo:

Sí, todo está correcto. Si quieres puedes eliminar todos los miembros eliminados, pero el constructor de copia borrado y de asignación de copia borrada y tienen el mismo efecto:

struct Picture { // Also ok 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 
}; 

La declaración expresa del constructor de copia inhibe la generación implícita del constructor por defecto, mover constructor y mover miembros de la asignación. La eliminación explícita de estos miembros es una cuestión de gusto. Algunos probablemente lo vean como una buena documentación. Otros pueden verlo como excesivamente detallado.

+1

Gracias, pasé por alto eso en el borrador del texto. Eso ahorra tiempo de tipeo. ¿Supongo que podría '= default' ellos si los quisiera? – towi

+1

Sí. Puede establecerlos explícitamente o eliminarlos explícitamente. –

3

Me parece bien. El valor de retorno de operator=debe ser ser una referencia normal, incluso si el objeto se construye a partir de una referencia rvalue. Esto se debe a que no puede simplemente compilar un lvalue (*this) a un valor r.
Y debería tomar esa referencia rvalue por no const Picture& operator=(Picture&&). ¿Cómo te moverías de un objeto constante? ;)

+0

Por supuesto, qué tonto de mi parte. Tienes razón en ambas cuentas. Permítanme corregirlo en la pregunta, para que los lectores no aprendan de mi ejemplo defectuoso. – towi

Cuestiones relacionadas