47 votes

Comment initialiser la structure de membre 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 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?

51voto

icecrime Points 23650

Tout d'abord, vous devriez vous (devez !) lire ce c++ faq concernant les POD et les agrégats. Dans votre cas, Foo est en effet un module de classe et d' foo() est une valeur d'initialisation :

La valeur d'initialiser un objet de type T signifie:

  • si T est un type de classe (clause 9) avec un utilisateur déclaré par le constructeur (12.1), puis le constructeur par défaut
    pour T est appelé (et l'initialisation est mal formé, si T n'a pas de accessible le constructeur par défaut);
  • si T est un non-union type de classe sans un utilisateur déclaré par le constructeur, puis tous les non-membre de données statiques et de la classe de base de la composante de T est la valeur initialisée;
  • si T est de type tableau, chaque élément est la valeur initialisée;
  • sinon, l'objet est initialisé à zéro

Donc oui, toto sera initialisé à zéro. Notez que si vous avez supprimé cette initialisation à partir d' Bar constructeur, foo ne serait défaut-initialisé :

Si aucun initialiseur est spécifié pour un objet, et l'objet est de (éventuellement cv qualifiés) non-POD type de classe (ou tableau de celui-ci), l'objet doit être par défaut-initialisé; si l'objet est de const qualifiés de type, le sous-jacent type de classe doit avoir un l'utilisateur déclaré dans le constructeur par défaut. Sinon, si pas de initialiseur est spécifié pour un non statique de l'objet, de la de l'objet et de ses sous-objets, le cas échéant, ont une durée indéterminée initiale valeur;

8voto

erjot Points 563

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X