Pregunta

C ++ 11 agrega la capacidad de decirle al compilador que crear una implementación predeterminada de cualquiera de las funciones especiales para miembros . Si bien puedo ver el valor de eliminar una función, ¿dónde está el valor de omitir explícitamente una función? Simplemente déjelo en blanco y el compilador lo hará de todos modos.

El único punto que puedo ver es que un constructor predeterminado solo se crea cuando no existe otro constructor:

class eg {
public:
    eg(int i);
    eg() = default; 
};

¿Pero es eso realmente mejor que cómo lo haces ahora?

class eg {
public:
    eg(int i);
    eg() {}
};

¿O me falta un caso de uso?

¿Fue útil?

Solución

Un constructor predeterminado tendrá una declaración, y esa declaración estará sujeta a las reglas de acceso normales. P.ej. puede hacer que el constructor de copia predeterminado esté protegido. Sin estas nuevas declaraciones, los miembros generados por defecto son públicos.

Otros consejos

Esos ejemplos del sitio web de Stroustrup pueden ayudarlo a comprender el punto:

  

funciones predeterminadas y eliminadas: control de valores predeterminados

     

El idioma común de `` prohibir   copiando " ahora se puede expresar   directamente:

class X {
  // ...

  X& operator=(const X&) = delete;    // Disallow copying
  X(const X&) = delete;
};
     

Por el contrario, también podemos decir explícitamente   que queremos predeterminar el comportamiento de copia:

class Y {
  // ...
  Y& operator=(const Y&) = default;   // default copy semantics
  Y(const Y&) = default;

};
     

Ser explícito sobre el valor predeterminado es   obviamente redundante, pero comenta   ese efecto y (peor) un usuario   definición explícita de operaciones de copia   destinado a dar el comportamiento predeterminado son   no poco comun. Dejándolo a la   compilador para implementar el valor predeterminado   el comportamiento es más simple, menos propenso a errores,   y a menudo conduce a un mejor código objeto.   El " predeterminado " mecanismo puede ser utilizado   para cualquier función que tenga un valor predeterminado.   El " eliminar " mecanismo puede ser utilizado para   cualquier función Por ejemplo, podemos   eliminar una conversión no deseada como   esto:

struct Z {
  // ...

  Z(long long);     // can initialize with an long long
  Z(long) = delete; // but not anything less
};

Además de cambiar la accesibilidad (privada / protegida) de las funciones generadas, podrá hacerlas virtuales.

struct S
{
    virtual ~S();
    virtual S& operator=(const S&);
};

S::~S() = default;
S& S::operator=(const S&) = default;

Se pueden modificar los siguientes aspectos de las funciones predeterminadas:

  • acceso (no público)
  • virtual
  • explícito (constructores)
  • especificaciones de excepción
  • constancia de parámetros

pero para hacerlo, las funciones deben definirse fuera de la clase (8.4.2 / 2 en Borrador final del Comité C ++ 0x ).

Una versión de la propuesta original de Lawrence Crowl es aquí .

Gracias a Roger Pate por la aclaración y la cita.

1) Los destructores generados implícitamente actualmente no son virtuales. Por lo tanto, debe definirlos para que sean virtuales, en cuyo caso no son tan eficientes. Con = predeterminado, tendrá destructores virtuales y eficientes como generadores generados implícitamente.

2) Tendrán especificadores de acceso, a diferencia de los generados implícitamente.

3) Si alineas tu constructor predeterminado, tu clase seguirá siendo trivial.

Aquí hay un artículo que elabora esta nueva característica.

Sospecho que ser capaz de generar por defecto el constructor de copias será realmente útil. No puedo ver un uso por defecto que genera el constructor predeterminado ya que, como usted dice, la implementación que escriba sería más corta.

Vea el Artículo 17 del gran libro de Scott Meyer " Effective Modern C ++ " ;. Describe muchas condiciones bajo las cuales se generan (o NO se generan) constructores de copia predeterminados, operaciones de copia y operaciones de movimiento.

En otras palabras, el compilador podría no "hacerlo de todos modos". Pero si la función de miembro especial predeterminada tiene sentido, el usuario podría usar el " predeterminado " palabra clave para indicar explícitamente al compilador que genere una función predeterminada que, de lo contrario, no se generaría.

De las cosas para recordar al final del artículo 17:

  
      
  • Las operaciones de movimiento se generan solo para clases que carecen de operaciones de movimiento declaradas explícitamente, operaciones de copia o destructor.

  •   
  • El constructor de copia se genera solo para las clases que carecen de un constructor de copia declarado explícitamente, y se elimina si se declara una operación de movimiento. El operador de asignación de copia se genera solo para las clases que carecen de un operador de asignación de copia declarado explícitamente, y se elimina si se declara una operación de movimiento. La generación de las operaciones de copia en clases con un destructor declarado explícitamente está en desuso.

  •   

Para mí, la función de desactivación será útil. Para la mayoría de las clases que creo actualmente, desactivo la copia & amp; asignación: será bueno tener una función que el compilador pueda reconocer para hacer esto, en lugar de depender de los errores del enlazador.

El valor predeterminado es más útil para los constructores de copias si tiene una clase con muchos atributos. Por ejemplo, si tiene esta clase:

class MyClass {
private:
   int offset;
   std::string name;
   std::vector<Person*> relatives;
   float weight;
   MyClass* spouse;
   Vehicle* car;
   double houseArea;
   Date birth;
   Person* parents[2];

public:
   /* Default constructor will be defined here */
};

en lugar de definir el constructor de copia de esta manera:

MyClass(const MyClass& that) :
   offset(that.offset),
   name(that.name),
   relatives(that.relatives),
   weight(that.weight),
   spouse(that.spouse),
   car(that.car),
   houseArea(that.houseArea),
   birth(that.birth),
   parents(that.parents)
{}

definirías de esta manera:

MyClass(const MyClass&) = default;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top