L'initialiseur de membre par défaut (default member initializer) est une construction de C++11 qui permet de déclarer des valeurs par défaut directement lors de la déclaration des variables membres d'une classe. Cette fonctionnalité est souvent confondue avec d'autres méthodes d'initialisation des données.
Les versions antérieures de C++ ne permettaient pas d'initialiser des membres directement lors de leur déclaration ; les valeurs n'étaient attribuées que dans le constructeur (dans le corps ou la liste d'initialisation). L'introduction des initialisateurs de membre par défaut (C++11) a amélioré la lisibilité et réduit le risque d'erreurs d'initialisation non définie.
Si les champs ne sont pas explicitement initialisés, ils contiennent une valeur "déchirée" (non définie). L'attribution dans le constructeur est moins efficace par rapport à la liste d'initialisation, et ignorer les initialisateurs de membre par défaut complique l'extension des classes et la création de nouveaux constructeurs.
Utilisez des initialisateurs de membre par défaut pour les valeurs simples, et pour les cas plus complexes (surtout s'il est nécessaire d'avoir une valeur dépendante ou non standard) — des listes d'initialisation de constructeur.
Exemple de code :
class Widget { int x = 42; // initialiseur de membre par défaut std::string name = "default"; // initialiseur de membre par défaut public: Widget() = default; // x=42, nom="default" Widget(int xx) : x(xx), name("new") {}// x=xx, nom="new" };
Caractéristiques clés :
L'initialiseur de membre par défaut s'applique-t-il si le membre est initialisé dans le corps du constructeur, mais pas dans la liste d'initialisation ?
Réponse :
Non. Si ce n'est pas indiqué dans la liste d'initialisation, la variable sera initialisée d'abord avec la valeur par défaut (initialiseur de membre par défaut), puis dans le corps du constructeur, ce qui est moins efficace.
Quel est l'ordre d'initialisation des membres de classe avec des initialisateurs de membre par défaut lors de l'héritage ?
Réponse :
Les membres de la classe de base sont initialisés en premier, suivis des membres de la classe dérivée ; pour chaque membre avec un initialiseur de membre par défaut, la liste d'initialisation du constructeur est utilisée en premier si elle est fournie, sinon l'initialiseur de membre par défaut est utilisé, sinon il reste non initialisé (pour POD). Il n'y a pas "deux fois l'initialisation".
Les initialisateurs de membre par défaut peuvent-ils être utilisés pour des membres static de la classe ?
Réponse :
Non, les membres static ne peuvent pas être initialisés par l'initialiseur de membre par défaut. Ils doivent être initialisés en dehors de la classe ou à l'aide de static inline en C++17.
Exemple :
struct S { static int a = 5; // Erreur ! };
Classe avec une chaîne dynamique, qui est oubliée lors de l'initialisation dans certains constructeurs. Plus tard lors de l'accès — comportement indéfini.
Avantages :
Inconvénients :
Tous les champs ont des initialisateurs de membre par défaut. Les constructeurs supplémentaires initialisent explicitement les membres requis si nécessaire via la liste d'initialisation.
Avantages :
Inconvénients :