¿Está bien dejar inutilizable un constructor predeterminado?

14

Preguntando específicamente sobre el constructor predeterminado

Dado que el constructor inicializa todos los datos de un objeto, si creo una clase que no se puede usar sin una inicialización adecuada, ¿no es el caso que el constructor predeterminado sea inútil? Considerar:

// A class for handling lines in a CSV file
class CSV_Entry {
private:
    unsigned num_entries;
    std::string string_version;
    std::vector<std::string> vector_version;
    ...etc
public:
    CSV_Entry();
    CSV_Entry(const std::string& src_line);

    // returns a vector copy of the original entry
    std::vector<std::string> get_vector_snapshot();
}

int main( void ) {
    ...etc

    CSV_Entry example = CSV_Entry();
    std::vector<std::string> current_entry = example.get_vector_snapshot();

    ...etc
}

Esa variable current_entryes esencialmente inútil no? Si alguien trata de procesarlo más tarde, es probable que obtenga errores; entonces crearían código para manejar tales errores ...

Para mitigar dicho código adicional e innecesario: ¿por qué no hacer que el constructor predeterminado sea inutilizable? Al igual que,

...etc

CSV_Entry() {
    throw Verbose_Exception( "CSV_Entry: do not use the default constructor" );
}

...etc

PD: en una nota al margen, si está bien simplemente dejar inutilizable el constructor predeterminado, ¿está bien poner ese lanzamiento en el encabezado, ya que de todos modos no se revelan otros detalles de implementación?

usuario2738698
fuente

Respuestas:

34

Sí, está bien (en realidad, es bueno ) hacer que el constructor predeterminado sea inutilizable si no hay una forma sensata de inicializar el objeto sin ningún argumento. Pero no lo "desactive" lanzando una excepción. Hazlo privado en su lugar. Idealmente, su interfaz no contendrá ningún método o constructor que las personas "no deben" llamar.

Doval
fuente
1
Entonces, al hacerlo privado, ¿el usuario que intenta usar el constructor predeterminado recibirá un error en el momento de la compilación?
user2738698
@ user2738698 Correcto.
Doval
8
Si usted puede utilizar C ++ 11, a continuación, marcar explícitamente como eliminado: CSV_Entry() = delete;.
bstamour
13
En realidad, ¿no es aún más fácil que esto? Si se definen constructores no predeterminados, el compilador no creará implícitamente un constructor predeterminado. Esta clase tiene un constructor no predeterminado definido (que recomendaría ser explicit, por cierto). Entonces, si simplemente no lo define, no existirá.
Fred Larson
77
@FredLarson Eliminarlo explícitamente expresa la intención de eliminarlo para que nadie piense que fue un error.
Darkhogg