En C++ el constructor por defecto es un constructor sin parámetros o con parámetros cuyos valores tienen por defecto. Si en la clase no se declara ningún constructor, el compilador generará automáticamente un constructor público por defecto. Sin embargo, si se declara al menos un cualquier otro constructor (por ejemplo, un constructor con parámetros), el constructor por defecto proporcionado automáticamente por el compilador ya no será generado. Si en tal clase se necesita un constructor por defecto, debe ser declarado explícitamente (por ejemplo, usando ClassName() = default;).
class Foo { public: Foo(int x) {} // Constructor del usuario // Foo() por defecto ya no será generado por el compilador! }; Foo f; // Error de compilación — ¡no hay constructor por defecto!
Para crear explícitamente un constructor por defecto en tal caso, se debe agregar:
class Foo { public: Foo() = default; Foo(int x) {} };
«Si solo tienes un constructor con parámetros, ¿se pueden crear objetos de esta clase sin parámetros? ¿Por qué?»
Respuesta: ¡No! Porque, si se declara cualquier constructor, el compilador ya no añade automáticamente el constructor por defecto. Para crear objetos sin parámetros, se debe añadir explícitamente el constructor por defecto en la declaración.
Historia
En un gran proyecto, se escribió una jerarquía de clases para la serialización de datos, donde todas las "clases hijas" tenían solo un constructor específico con parámetros. Después de la refactorización, resultó que al usar contenedores STL (por ejemplo, std::vector) con estas clases, la compilación fallaba: el contenedor necesitaba un constructor por defecto, que no existía. El problema se resolvió solo después de declarar explícitamente el constructor por defecto.
Historia
En un proyecto que usa templating, una de las clases adaptadoras solo declaró el constructor con parámetros para pasar recursos. Sin embargo, una de las bibliotecas requería la presencia de un constructor por defecto para un funcionamiento correcto (creando objetos temporales a través de tipos de plantillas). Surgieron misteriosos errores de enlace que no pudieron explicarse durante mucho tiempo, hasta que se implementó el constructor por defecto explícito.
Historia
En el código, hubo una migración de C++98 a C++11, y se intentó usar "= default" para la declaración explícita del constructor por defecto. En los compiladores antiguos surgieron errores o se ignoraron nuevas construcciones sintácticas. Esto reveló que no todos los desarrolladores comprenden la diferencia entre un constructor por defecto implementado explícitamente, uno generado por el compilador, y la nueva sintaxis "= default".