Ordre d'évaluation de la liste d'initialisation du constructeur

252

J'ai un constructeur qui prend quelques arguments. J'avais supposé qu'ils ont été construits dans l'ordre indiqué, mais dans un cas, il semble qu'ils étaient construits à l'envers, ce qui a entraîné un avortement. Lorsque j'ai inversé les arguments, le programme a cessé d'interrompre. Ceci est un exemple de la syntaxe que j'utilise. Le fait est que a_ doit être initialisé avant b_ dans ce cas. Pouvez-vous garantir l'ordre de construction?

par exemple

class A
{
  public:
    A(OtherClass o, string x, int y) :
      a_(o), b_(a_, x, y) { }

    OtherClass a_;
    AnotherClass b_;
};
Mat
la source
6
Vous dites que vous posez des questions sur les arguments du constructeur, mais ils sont évalués avant que vous n'atteigniez le constructeur, et ils sont évalués dans un ordre non spécifié, déterminé par le compilateur. Mais vous demandez vraiment l'ordre des listes d'initialisation, j'ai donc changé le titre de la question pour vous.
Rob Kennedy

Réponses:

278

Cela dépend de l'ordre de déclaration des variables membres dans la classe. Ce a_sera le premier, puis b_le second dans votre exemple.

AraK
la source
22
En fait, les bons compilateurs avertiront si vous avez un ordre différent dans la déclaration par rapport à la liste d'initialisation du constructeur. Par exemple, voir -Wreorderdans gcc.
Greg Hewgill
236
La raison pour laquelle ils sont construits dans l'ordre de déclaration des membres et non dans l'ordre dans le constructeur est que l'on peut avoir plusieurs constructeurs, mais il n'y a qu'un seul destructeur. Et le destructeur détruit les membres dans l'ordre inverse de la construction.
AProgrammer
3
voulions-nous dire ... ordre de déclaration inverse. Pas de "construction", le destructeur ne peut pas voir dans le constructeur pour le savoir?
Conrad B
196

Pour citer la norme, pour clarification:

12.6.2.5

L'initialisation se déroule dans l'ordre suivant:

...

  • Ensuite, les membres de données non statiques doivent être initialisés dans l'ordre dans lequel ils ont été déclarés dans la définition de classe (là encore, quel que soit l'ordre des initialiseurs mem).

...

GManNickG
la source
18

La référence standard pour cela semble maintenant être la section 13.3 de la section 12.6.2:

(13.3) - Ensuite, les membres de données non statiques sont initialisés dans l'ordre dans lequel ils ont été déclarés dans la définition de classe (à nouveau indépendamment de l'ordre des initialiseurs mem).

Adam Getchell
la source