programas programación programacion predefinidas para ingenieros funciones ejemplos comandos basico avanzados c++ c++11 defaulted-functions

programación - ¿Qué sentido tienen las funciones predeterminadas en C++ 11?



programas en c++ ejemplos avanzados (8)

C ++ 11 agrega la capacidad de decirle al compilador que cree una implementación predeterminada de cualquiera de las funciones miembro especiales . Si bien puedo ver el valor de eliminar una función, ¿dónde está el valor de predeterminar explícitamente una función? Solo déjalo 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 realmente mejor que cómo lo haces ahora?

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

¿O me estoy perdiendo un caso de uso?


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

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

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

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


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 (hacerse no público)
  • virtual
  • explícito (constructores)
  • especificaciones de excepción
  • constancia de los parámetros

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

Una versión de la propuesta original de Lawrence Crowl está here .

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


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

Funciones predeterminadas y eliminadas - control de valores predeterminados

El lenguaje común de "prohibir la copia" ahora se puede expresar directamente:

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

A la inversa, también podemos decir explícitamente que queremos el comportamiento de copia predeterminado:

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

Evidentemente, ser explícito sobre el valor predeterminado es redundante, pero los comentarios a ese efecto y (lo que es peor) un usuario que define explícitamente las operaciones de copia destinadas a dar el comportamiento predeterminado no son infrecuentes. Dejarlo en el compilador para implementar el comportamiento predeterminado es más simple, menos propenso a errores y, a menudo, conduce a un mejor código de objeto. El mecanismo "predeterminado" se puede utilizar para cualquier función que tenga un valor predeterminado. El mecanismo de "eliminar" se puede utilizar para cualquier función. Por ejemplo, podemos eliminar una conversión no deseada como esta:

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


La configuración predeterminada es más útil para los constructores de copia si tiene una clase con muchos atributos. Por ejemplo, si tienes 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) {}

Usted definiría de esta manera:

MyClass(const MyClass&) = default;


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


Sospecho que ser capaz de generar por defecto el constructor de copia será realmente útil. No puedo ver un uso para la generación predeterminada del constructor predeterminado porque, como usted dice, la implementación que ingrese será más corta.


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


Vea el artículo 17 del gran libro de Scott Meyer " Efectivo C ++ moderno ". 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 la palabra clave "predeterminada" para decirle explícitamente al compilador que genere una función predeterminada que, de lo contrario, no se generará.

De las Cosas para recordar al final del punto 17:

  • Las operaciones de movimiento se generan solo para las clases que carecen de operaciones de movimiento explícitamente declaradas, operaciones de copia o un 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 explícitamente declarado, 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.