¿Se generan constructores de movimiento/operadores de asignación para clases derivadas?

Si la clase X se deriva de la clase Y y la clase Y tiene cualquiera de:

  • Un constructor de copia declarado por el usuario,
  • Un operador de asignación de copia declarado por el usuario,
  • Un destructor declarado por el usuario
  • Un constructor de movimiento declarado por el usuario,
  • Un operador de asignación de movimiento declarado por el usuario,

¿Se predeterminará implícitamente un constructor de movimiento y un operador de asignación de movimiento para la clase X siempre que no declare nada de lo anterior?

p.ej

struct Y
{
     virtual ~Y() {}

     // .... stuff

};

struct X : public Y
{
   // ... stuff but no destructor, 
   //               no copy/move assignment operator 
   //               no copy/move constructor

   // will X have a default move constructor / assignment operator?
};

Actualmente estoy usando gcc, pero estoy principalmente interesado en cuál debería ser el comportamiento correcto (a diferencia de si un compilador en particular cumple o no con los estándares).

preguntado el 22 de mayo de 12 a las 11:05

No relacionado con su asunto, pero en caso de que no lo sepa con C++ 11, ahora puede hacer virtual ~Y() = default; en lugar de definir el destructor usted mismo (aunque quizás su compilador aún no lo admita). -

@Luc Danton Por interés, si tuviera que usar virtual ~Y() = default; ¿Eso activará el compilador para que implique implícitamente el constructor de movimiento/operador de asignación? ¿O necesitaría establecer explícitamente estas operaciones por defecto? -

@mark: no, no lo hará, porque el destructor predeterminado explícitamente es un destructor definido por el usuario. -

2 Respuestas

En lo que respecta a la clase derivada, no importa el hecho de que un atributo o una clase base tenga funciones especiales definidas por el usuario o implícitas. Todo lo que importa es su presencia.

Los compiladores compatibles con C ++ 11 deberían proporcionar automáticamente los constructores de movimiento y los operadores de asignación para la estructura y la clase, si es posible (que está claramente definido en el Estándar), aunque solo las clases con búfer asignados dinámicamente se beneficiarán realmente de esto (mover un int solo lo está copiando).

Por lo tanto, si su clase incrusta un std::string o con una std::unique_ptr (por ejemplo), entonces su constructor de movimiento llamará al incrustado string or unique_ptr move constructor y será eficiente... gratis.

Simplemente cambiando el modo de compilación debería mejorar ligeramente el rendimiento.

contestado el 22 de mayo de 12 a las 11:05

Sí, lo son, en §12.8.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,
  • X no tiene un destructor declarado por el usuario y
  • el constructor de movimiento no se definiría implícitamente como eliminado.

y §12.8.10

El constructor de movimiento declarado implícitamente para la clase X tendrá la forma

X::X(X&&)

De manera similar, para mover operadores de asignación en 12.8.20:

Si la definición de una clase X no declara explícitamente un operador de asignación 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 constructor de movimiento declarado por el usuario,
  • X no tiene un operador de asignación de copia declarado por el usuario,
  • X no tiene un destructor declarado por el usuario y
  • el operador de asignación de movimiento no se definiría implícitamente como eliminado.

Las clases base no entran directamente.

contestado el 22 de mayo de 12 a las 11:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.