lists initialize enclosed brace c++ initialization undefined-behavior standards-compliance ctor-initializer

initialize - list initialization c++



Dependencias en las listas de inicialización (3)

¿Está este comportamiento bien definido?

class Foo { int A, B; public: Foo(int Bar): B(Bar), A(B + 123) { } }; int main() { Foo MyFoo(0); return 0; }



No, el orden de inicialización está definido por el orden de declaración en la propia clase.

Del estándar C ++ 12.6.2 [class.base.init] p5 :

La inicialización se realizará en el siguiente orden:
- Primero, y solo para el constructor de la clase más derivada como se describe a continuación, las clases base virtuales se inicializarán en el orden en que aparecen en un primer recorrido de izquierda a derecha del gráfico acíclico dirigido de clases base, donde “ De izquierda a derecha ”es el orden de aparición de los nombres de clase base en la clase derivada base-especificador-lista.
- Luego, las clases base directas se inicializarán en el orden de declaración tal como aparecen en la lista de especificadores de base (independientemente del orden de los inicializadores de memoria).
- Luego, los miembros de datos no estáticos se inicializarán en el orden en que fueron declarados en la definición de la clase (de nuevo, independientemente del orden de los inicializadores de memoria).
- Finalmente, se ejecuta el cuerpo del constructor.
[Nota: el orden de declaración es obligatorio para garantizar que los subobjetos base y miembro se destruyan en el orden inverso de inicialización. ]


No, no está definido. A se inicializará primero (es el primero en la definición de la clase) y usa B inicializar.

Los miembros de la clase se inicializan en el orden en que aparecen en la definición de clase, independientemente de su orden en la lista de inicialización. De hecho, es una mala práctica desajustar el orden de definición del miembro con el orden de la lista de inicialización.

Si tu instancia de Foo tuvo una duración estática, como en Foo f(0); int main(){} Foo f(0); int main(){} , el comportamiento está bien definido. Los objetos con duración estática se inicializan con cero antes de que tenga lugar cualquier otra inicialización; en ese caso, A y B serán 0 cuando se ejecute el constructor. Después de eso, sin embargo, el comportamiento es el mismo: primero A luego B , dando a A un valor de 123 y B un valor de Bar (todavía feo).