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 souhaite initialiser la structure "foo" (avec tous ses membres) à zéro dans l'initialiseur de la classe Bar. Cela peut-il être fait de cette façon:
Bar::Bar()
: foo(),
x(8) {
}
...?
Ou que fait exactement 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 ceci c ++ faq concernant le POD et les agrégats. Dans votre cas, Foo
est en effet une classe POD et foo()
est une initialisation de valeur :
Pour initialiser en valeur un objet de type T, cela signifie:
- si T est un type de classe (article 9) avec un constructeur déclaré par l'utilisateur (12.1), alors le constructeur par défaut
pour 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, alors chaque membre de données non statique et composant de classe de base de T est initialisé en valeur;
- si T est un type de tableau, alors chaque élément est initialisé en valeur;
- sinon, l'objet est initialisé à zéro
Alors oui, foo sera initialisé à zéro. Notez que si vous supprimiez cette initialisation du constructeur Bar
, foo
ne serait initialisé par défaut :
Si aucun initialiseur n'est spécifié pour un objet et que l'objet est de type de classe (éventuellement qualifié par cv) non POD (ou un tableau de celui-ci), l'objet doit être initialisé par défaut; si l'objet est de type qualifié const, 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 objet non statique, l'objet et ses sous-objets, le cas échéant, ont une valeur initiale indéterminée ;
En C++ standard, vous devez créer un ctor pour Foo.
struct Foo {
Foo(int const a, std::initializer_list<char> 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 toujours 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 à Foo un ctor par défaut.