Peut-on rendre un constructeur par défaut inutilisable?

14

Poser des questions spécifiques sur le constructeur par défaut

Étant donné que le constructeur initialise toutes les données d'un objet, si je crée une classe qui ne peut pas être utilisée sans une bonne initialisation, n'est-il pas vrai que le constructeur par défaut est inutile? Considérer:

// 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
}

Cette variable current_entryest essentiellement inutile non? Si quelqu'un essaie de le traiter plus tard, il obtiendrait probablement des erreurs; puis ils créeraient du code pour gérer ces erreurs ...

Pour atténuer ce code supplémentaire inutile: pourquoi ne pas rendre le constructeur par défaut inutilisable? Ainsi,

...etc

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

...etc

PS: en passant, s'il est bien de rendre le constructeur par défaut inutilisable, est-ce bien de mettre ce lancer dans l'en-tête, car aucun autre détail d'implémentation n'est révélé de toute façon?

user2738698
la source

Réponses:

34

Oui, c'est bien (en fait, c'est bien ) de rendre le constructeur par défaut inutilisable s'il n'y a pas de moyen sensé d'initialiser l'objet sans aucun argument. Mais ne le "désactivez" pas en lançant une exception. Rendez-le privé à la place. Idéalement, votre interface ne contiendra aucune méthode ou constructeur que les gens "ne sont pas censés" appeler.

Doval
la source
1
Donc, en le rendant privé, l'utilisateur qui essaie d'utiliser le constructeur par défaut obtiendra une erreur au moment de la compilation?
user2738698
@ user2738698 Correct.
Doval
8
Si vous pouvez utiliser C ++ 11, puis marquer explicitement comme supprimé: CSV_Entry() = delete;.
bstamour
13
En fait, n'est-ce pas encore plus facile que ça? Si des constructeurs non définis par défaut sont définis, le compilateur ne créera pas implicitement un constructeur par défaut. Cette classe a un constructeur non défini par défaut (ce que je recommanderais explicit, BTW). Donc, si vous ne le définissez pas, il n'existera pas.
Fred Larson
7
@FredLarson La suppression explicite exprime l'intention de la supprimer afin que personne ne pense que c'était une erreur.
Darkhogg