Comment initialiser member-struct dans la liste d’initialisation de la classe C ++?

J’ai les définitions de classe suivantes en c ++:

struct Foo { int x; char array[24]; short* y; }; class Bar { Bar(); int x; Foo foo; }; 

et voudrait initialiser la structure “foo” (avec tous ses membres) à zéro dans l’initialiseur de la classe Bar. Est-ce que cela peut être fait de cette façon:

 Bar::Bar() : foo(), x(8) { } 

…?

Ou que fait exactement le foo (x) dans la liste d’initialisation?

Ou la structure est-elle même initialisée automatiquement à zéro à partir du compilateur?

Tout d’abord, vous devriez (devez!) Lire cette FAQ c ++ concernant le POD et les agrégats. Dans votre cas, Foo est bien une classe POD et foo() est une initialisation de valeur :

Valoriser-initialiser un object de type T signifie:

  • si T est un type de classe (clause 9) avec un constructeur déclaré par l’utilisateur (12.1), alors le constructeur par défaut
    car T est appelé (et l’initialisation est mal formée si T n’a pas de constructeur par défaut accessible);
  • si T est un type de classe non-union sans constructeur déclaré par l’utilisateur, chaque composant de données et composant de classe de base non statique de T est initialisé en valeur;
  • si T est un type tableau, alors chaque élément est initialisé en valeur;
  • sinon, l’object est initialisé à zéro

Donc oui, toto sera initialisé à zéro. Notez que si vous supprimez cette initialisation du constructeur Bar , l’initialisation de foo ne sera effectuée que par défaut :

Si aucun initialiseur n’est spécifié pour un object et que l’object appartient à un type de classe non POD (ou à un tableau de celui-ci) (éventuellement qualifié de cv), l’object doit être initialisé par défaut; Si l’object est de type qualifié, le type de classe sous-jacent doit avoir un constructeur par défaut déclaré par l’utilisateur. Sinon, si aucun initialiseur n’est spécifié pour un object non statique, l’object et ses sous-objects, le cas échéant, ont une valeur initiale indéterminée ;

En standard C ++, vous devez créer un moteur pour Foo.

 struct Foo { Foo(int const a, std::initializer_list const b, short* c) : x(a), y(c) { assert(b.size() >= 24, "err"); std::copy(b.begin(), b.begin() + 24, array); } ~Foo() { delete y; } int x; char array[24]; short* y; }; class Bar { Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'}, new short(5)) { } private: int x; Foo foo; }; 

En C ++ 0x, vous pouvez utiliser une liste d’initialisation uniforme, mais vous avez tout de même besoin de dtor pour Foo:

 class Bar { Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'}, new short(5)} { } ~Bar() { delete[] foo.array; delete foo.y;} } private: int x; Foo foo; }; 

Pour initialiser par défaut foo (comme Bar() : foo(), x(8) { } ), vous devez donner un facteur par défaut à Foo.