Editar. En realidad, aunque lo que digo en mi primera respuesta es válido, esta es la verdadera razón:
Al principio existía C. C no está orientado a objetos (puede adoptar un enfoque OO, pero no lo ayuda ni impone nada).
Luego estaba C With Classes, que luego pasó a llamarse C ++. C ++ está orientado a objetos y, por lo tanto, fomenta la encapsulación y garantiza la invariabilidad de un objeto: después de la construcción y al principio y al final de cualquier método, el objeto está en un estado válido.
Lo natural que se debe hacer con esto es hacer cumplir que una clase siempre debe tener un constructor para garantizar que comience en un estado válido; si el constructor no tiene que hacer nada para garantizarlo, el constructor vacío documentará este hecho. .
Pero un objetivo con C ++ era ser compatible con C hasta el punto de que, en la medida de lo posible, todos los programas válidos de C también eran programas válidos de C ++ (ya no es un objetivo tan activo, y la evolución de C separada de C ++ significa que ya no se cumple )
Un efecto de esto fue la duplicación en la funcionalidad entre struct
y class
. El primero hace las cosas a la manera C (todo público por defecto) y el segundo hace las cosas de una buena manera OO (todo lo privado por defecto, el desarrollador hace público lo que quiere público).
Otra es que para que una C struct
, que no podría tener un constructor porque C no tiene constructores, sea válida en C ++, tenía que haber un significado para esto en la forma de verla en C ++. Y así, aunque no tener un constructor iría en contra de la práctica OO de asegurar activamente una invariante, C ++ tomó esto como que significaba que había un constructor sin parámetros predeterminado que actuaba como si tuviera un cuerpo vacío.
Todos los C structs
ahora eran C ++ válidos structs
, (lo que significaba que eran lo mismo que C ++ classes
con todo, miembros y herencia, público) tratados desde el exterior como si tuviera un único constructor sin parámetros.
Sin embargo, si puso un constructor en una class
o struct
, entonces estaba haciendo las cosas de la manera C ++ / OO en lugar de la forma C, y no había necesidad de un constructor predeterminado.
Dado que sirvió como una abreviatura, la gente siguió usándolo incluso cuando la compatibilidad no era posible de otra manera (usaba otras características de C ++ que no estaban en C).
Por lo tanto, cuando apareció Java (basado en C ++ de muchas maneras) y luego C # (basado en C ++ y Java de diferentes maneras), mantuvieron este enfoque como algo a lo que los codificadores ya pueden estar acostumbrados.
Stroustrup escribe sobre esto en su lenguaje de programación The C ++ y aún más, con un mayor enfoque en los "porqués" del lenguaje en The Design and Evolution of C ++ .
=== Respuesta original ===
Digamos que esto no sucedió.
Digamos que no quiero un constructor sin parámetros, porque no puedo poner mi clase en un estado significativo sin uno. De hecho, esto es algo que puede suceder struct
en C # (pero si no puede hacer un uso significativo de todos ceros y nulos struct
en C #, en el mejor de los casos, está utilizando una optimización no visible públicamente y, de lo contrario, tiene un falla de diseño en el uso struct
).
Para que mi clase pueda proteger a sus invariantes, necesito una removeDefaultConstructor
palabra clave especial . Por lo menos, necesitaría crear un constructor privado sin parámetros para asegurarme de que ningún código de llamada llame al valor predeterminado.
Lo que complica aún más el lenguaje. Mejor no hacerlo.
En general, es mejor no pensar en agregar un constructor como eliminar el valor predeterminado, mejor pensar en no tener ningún constructor como azúcar sintáctica para agregar un constructor sin parámetros que no haga nada.