web-dev-qa-db-fra.com

Le constructeur doit-il initialiser tous les membres de la classe?

J'ai une situation comme celle-ci:

class A {
public:
  A() : n(0) {}
private:
  int n;
  int m;
}

Il n'y a tout simplement aucune signification dans la logique d'application d'initialiser m dans le constructeur. Cependant, Eclipse me prévient que le constructeur laisse m non initialisé. Je ne peux pas exécuter le code ailleurs que maintenant. L'avertissement est:

Le membre 'm' n'a pas été initialisé dans ce constructeur

C++ nous incite-t-il à initialiser tous les membres de données du constructeur ou s'agit-il simplement de la logique d'Eclipse?

13
gsamaras

Le constructeur doit-il initialiser tous les membres de la classe?

Ce serait une bonne pratique.

Alors, C++ nous encourage-t-il à initialiser tous les membres de données dans le constructeur?

Ce n'est pas requis par le standard c ++. Tant que vous initialisez toutes les variables avant leur utilisation, votre programme est correct à cet égard.

ou est-ce juste la logique d'Eclipse? 

Plutôt probable. Ni les versions g ++ ni clang que j'ai testées ne le préviennent lorsque tous les avertissements sont activés. La logique peut être ou non basée sur la norme de codage C++ à haute intégrité 12.4.2 ou une autre norme de codage ou un guide de style.

12
eerorika

C++ ne nécessite pas que les attributs soient initialisés dans le constructeur, sauf dans le cas d'attributs const où la valeur doit être définie dans la liste d'initialisation.

Cependant, il est clairement recommandé d'initialiser tous les attributs dans le constructeur. Je ne peux pas compter le nombre de bogues rencontrés à cause d'une variable ou d'attributs non initialisés.

Enfin, chaque objet doit en permanence être dans un consistent state, qui inclut à la fois des attributs publics (accessibles) et des attributs privés. L'optimisation ne doit pas être une raison pour maintenir un objet incohérent.

5
toubab

Pour être complet, l'avertissement provient de l'analyse de code C/C++. En particulier, le problème est Potential Programming Problems/Class members should be properly initialized

Pour modifier les paramètres d'analyse du code (dans ce cas, je recommande par projet), modifiez les propriétés du projet. Vous pouvez désactiver l’avertissement complet ou uniquement sur les fichiers qui ne respectent pas la condition d’avertissement.

 show the warning

En ce qui concerne la comparaison de CDT avec GCC ou CLang, il semble que ce soit un cas où CDT effectue une analyse de code supplémentaire par rapport à ce qui est disponible auprès des compilateurs. Bien entendu, il fallait s'y attendre, car le mandat de la CDT Code Analysis est supérieur à celui du compilateur.

PS, si vous le souhaitez, vous pouvez lire l’implémentation de ce vérificateur particulier .

5
Jonah Graham

Totalement en désaccord avec toutes les réponses et commentaires. Il n'est absolument pas nécessaire d'initialiser un membre par défaut lorsqu'il n'est pas utilisé. C'est pourquoi C/C++ n'initialise jamais les types intégrés en tant que membres ou variables automatiques, car cela entraverait les performances. Bien sûr, ce n’est pas un problème si vous créez votre objet/variable une seule fois (c’est pourquoi les statiques sont initialisées par défaut), mais pour quelque chose qui se passe dans une boucle serrée, l’initialisation par défaut peut prendre de précieuses nanosecondes.

À mon avis, la seule exception à cette règle serait les pointeurs (si vous avez des pointeurs bruts dans votre code). Les pointeurs bruts doivent être initialisés à NULL, car avoir un pointeur invalide est un moyen direct de générer un comportement indéfini.

1
SergeyA

Comme cela a déjà été dit, vous devriez toujours initialiser les pointeurs et bien sûr les objets const sont obligatoires.

À mon avis, vous ne devriez pas initialiser quand ce n’est pas nécessaire, mais il est bon de vérifier de temps en temps toutes les variables non initialisées par le constructeur, car elles sont à la source de bogues très fréquents et difficiles à trouver.

Je lance Cppcheck tous les quelques mois. Cela me donne plus de cent avertissements "faux" comme "La variable membre" foo :: bar "n'est pas initialisée dans le constructeur." mais de temps en temps, il découvre de vrais bugs, donc il en vaut la peine.

0
rockefelox