Orden de evaluación de la lista de inicialización del constructor

252

Tengo un constructor que toma algunos argumentos. Supuse que se construyeron en el orden indicado, pero en un caso parece que se construyeron en reversa, lo que resultó en un aborto. Cuando invertí los argumentos, el programa dejó de abortar. Este es un ejemplo de la sintaxis que estoy usando. La cuestión es que a_ necesita inicializarse antes que b_ en este caso. ¿Pueden garantizar el orden de construcción?

p.ej

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

    OtherClass a_;
    AnotherClass b_;
};
Mate
fuente
66
Dice que está preguntando acerca de los argumentos del constructor, pero se evalúan antes de llegar al constructor, y se evalúan en un orden no especificado y determinado por el compilador. Pero realmente está preguntando sobre el orden de las listas de inicialización, por lo que he cambiado el título de la pregunta para usted.
Rob Kennedy el

Respuestas:

278

Depende del orden de la declaración de la variable miembro en la clase. Entonces a_será el primero, luego b_será el segundo en su ejemplo.

AraK
fuente
22
De hecho, los buenos compiladores le avisarán si tiene un orden diferente en la declaración frente a la lista de inicializadores del constructor. Por ejemplo, ver -Wreorderen gcc.
Greg Hewgill el
236
La razón por la cual se construyen en el orden de declaración de miembro y no en el orden en el constructor es que uno puede tener varios constructores, pero solo hay un destructor. Y el destructor destruye a los miembros en el orden de construcción.
Programador del
3
queríamos decir ... orden inverso de declaración. No es de "construcción", el destructor no puede ver el constructor para saber ¿verdad?
Conrad B
196

Para citar el estándar, para aclarar:

12.6.2.5

La inicialización se realizará en el siguiente orden:

...

  • Luego, los miembros de datos no estáticos se inicializarán en el orden en que se declararon en la definición de clase (nuevamente, independientemente del orden de los inicializadores de memoria).

...

GManNickG
fuente
18

La referencia estándar para esto ahora parece ser 12.6.2 sección 13.3:

(13.3) - Luego, los miembros de datos no estáticos se inicializan en el orden en que fueron declarados en la definición de clase (nuevamente, independientemente del orden de los inicializadores de memoria).

Adam Getchell
fuente