14.3. La lista de inicialización del constructor

Ya ha visto lo importante que es en C++ garantizar una correcta inicialización, y esto no cambia en la composición ni en la herencia. Cuando se crea un objeto, el compilador garantiza la ejecución de los constructores de todos sus subobjetos. Hasta ahora, en los ejemplos, todos los subobjetos tienen un constructor por defecto, que es lo que el compilador llama automáticamente. Pero ¿qué ocurre si sus subobjetos no tienen constructores por defecto, o si quiere cambiar un argumento por defecto de un constructor? Esto supone un problema, porque el constructor de la nueva clase no tiene permiso para acceder a los atributos privados del subobjeto y por ello no puede inicializarlos directamente.

La solución es simple: llamar al constructor del subobjeto. C++ proporciona una sintaxis especial para ello, la lista de inicialización del constructor. La forma de la lista de inicialización del constructor recuerda a la de la herencia. En la herencia, las clases base se colocan después de dos puntos y antes de la llave de apertura del cuerpo de la clase. En la lista de inicialización del constructor, las llamadas a los constructores de los subobjetos se colocan después de la lista de argumentos del constructor y de dos puntos, pero antes de la llave de apertura del cuerpo de la función. Para una clase MyType que hereda de Bar, tendría este aspecto:

MyType::MyType(int i) : Bar(i) { // ...

si Bar tiene un constructor que recibe un único argumento de tipo int.

14.3.1. Inicialización de objetos miembro

Resulta que esta misma sintaxis se utiliza para inicializar los objetos miembro cuando se usa la composición. En la composición, se indican los nombres de los objetos en lugar de los nombres de las clases. Si hay más de una llamada a constructor en la lista de inicialización, las llamadas se separan con comas:

MyType2::MyType2(int i) : Bar(i), m(i+1) { // ...

Éste es el comienzo de un constructor de la clase MyType2, que hereda de Bar y contiene un objeto miembro llamado m. Fíjese en que, mientras que en la lista de inicialización del constructor aparece el tipo de la clase base, del objeto miembro sólo aparece el identificador.