c++ - programacion - ¿Se pueden usar las variables miembro para inicializar otros miembros en una lista de inicialización?
ejercicios resueltos de poo en c++ (4)
Esto es bien definido y portátil, 1 pero es potencialmente propenso a errores.
Los miembros se inicializan en el orden en que se declaran en el cuerpo de la clase, no en el orden en que aparecen en la lista de inicialización. Entonces, si cambia el cuerpo de la clase, este código puede fallar silenciosamente (aunque muchos compiladores detectarán esto y emitirán una advertencia).
1. De [class.base.init] en los estándares de C ++:En un constructor no delegante, la inicialización se realiza en el siguiente orden:
- Primero, y solo para el constructor de la clase más derivada (1.8), las clases de base virtual se inicializan en el orden en que aparecen en un primer recorrido de izquierda a derecha del gráfico acíclico dirigido de clases de base, donde a la derecha es el orden de aparición de las clases base en la lista derivada de especificación de base de clase.
- Luego, las clases básicas directas se inicializan 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 inicializan 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 la declaración compuesta del cuerpo del constructor.
(Destacar es mío.)
Esta sección de la norma continúa para dar un ejemplo del uso de variables miembro para inicializar otras variables miembro.
Considere la siguiente situación (simplificada):
class Foo
{
private:
int evenA;
int evenB;
int evenSum;
public:
Foo(int a, int b) : evenA(a-(a%2)), evenB(b-(b%2)), evenSum(evenA+evenB)
{
}
};
Cuando yo instalo a Foo así:
Foo foo(1,3);
entonces evenA es 0, evenB es 2, pero evenSum se inicializará a 2?
Intenté esto en mi plataforma actual (iOS) y parece funcionar, pero no estoy seguro de si este código es portátil.
¡Gracias por tu ayuda!
Esto también se compiló sin error en g ++ 4.0.3 (6 años ahora).
Estoy seguro de que esto se compilará bien en cualquier compilador razonablemente reciente.
Los miembros se inicializan en el orden en que se declaran en la definición de clase. Siempre que su lista de inicializadores siga este orden, debería estar bien.
Sí, siempre que ya hayan sido construidos. Simplemente no olvide que el orden de construcción es el orden de las declaraciones en la definición de clase, no el orden de los inicializadores en el constructor. Y que el compilador normalmente no le dirá si usa una variable antes de que se haya construido. En su caso, por ejemplo, si mueve evenSum
al principio de la clase, tiene un comportamiento indefinido (porque su inicializador usa miembros no inicializados), aunque en su constructor, inicialice evenA
y evenB
léxicamente antes de evenSum
.