Menu
Coddy logo textTech

Listas de inicialización del constructor

Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy — lección 22 de 104.

Has visto la sintaxis de dos puntos en lecciones anteriores como Player(std::string n, int h) : name(n), health(h) {}. Esto se llama una lista de inicialización de miembros, y es la forma preferida de inicializar miembros en C++.

La lista de inicialización aparece después de la lista de parámetros del constructor, comenzando con dos puntos. Cada miembro se inicializa directamente con su valor, separados por comas:

class Rectangle {
    int width;
    int height;
    const int id;
    int& reference;
public:
    Rectangle(int w, int h, int i, int& r) 
        : width(w), height(h), id(i), reference(r) {
        // Cuerpo del constructor (puede estar vacío)
    }
};

¿Por qué usar listas de inicialización en lugar de la asignación en el cuerpo del constructor? Con la asignación, los miembros se construyen primero por defecto y luego se les asignan nuevos valores. Con las listas de inicialización, los miembros se construyen directamente con los valores correctos: más eficiente y, a veces, obligatorio.

Ciertos miembros deben ser inicializados usando la lista:

  • miembros const - no se pueden asignar después de la construcción
  • Miembros de referencia - deben vincularse en la inicialización
  • Miembros sin constructores por defecto
class Player {
    const int maxHealth;    // Debe usar una lista de inicialización
    std::string name;
public:
    // Esto funciona
    Player(int max, std::string n) : maxHealth(max), name(n) {}
    
    // Esto NO compilaría:
    // Player(int max) { maxHealth = max; }  // ¡Error!
};

Los miembros se inicializan en el orden en que están declarados en la clase, no en el orden de la lista de inicialización. Escriba siempre su lista de inicialización en el orden de declaración para evitar confusiones.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de configuración para un motor de juegos que demuestre cuándo y por qué las listas de inicialización de miembros son esenciales. Crearás una clase GameConfig con miembros que deben inicializarse utilizando la sintaxis de lista de inicialización.

Crearás dos archivos para organizar tu código:

  • GameConfig.h: Define una clase GameConfig que almacene los ajustes del juego. Tu clase debe tener:
    • Un const std::string gameName — el título del juego, que no puede cambiar después de la creación
    • Un const int maxPlayers — el recuento máximo de jugadores, fijo en la construcción
    • Un int& difficultyRef — una referencia a un ajuste de dificultad externo
    • Un int screenWidth e int screenHeight — miembros regulares para los ajustes de pantalla
    • Un constructor que tome todos los parámetros necesarios e inicialice cada miembro utilizando la lista de inicialización. La lista de inicialización debe seguir el orden en que se declaran los miembros en la clase
    • Un método display() que imprima la configuración en este formato:
      Game: <gameName>
      Max Players: <maxPlayers>
      Difficulty: <difficultyRef value>
      Resolution: <screenWidth>x<screenHeight>
  • main.cpp: Lee los valores de configuración de la entrada y crea un objeto GameConfig. Necesitarás:
    • Leer el nombre del juego (string), el máximo de jugadores (int), la dificultad (int), el ancho (int) y el alto (int) de la entrada — cada uno en una línea separada
    • Crear una variable local int para la dificultad a la que hará referencia la configuración
    • Crear un objeto GameConfig utilizando el constructor con lista de inicialización
    • Llamar a display() para mostrar la configuración inicial
    • Modificar la variable de dificultad directamente (multiplicándola por 2)
    • Imprimir "After difficulty change:"
    • Llamar a display() de nuevo para mostrar que la referencia refleja el valor actualizado

Este desafío resalta por qué las listas de inicialización son importantes: tus miembros const y el miembro de referencia no pueden ser asignados en el cuerpo del constructor — deben ser inicializados en la lista. El miembro de referencia también demuestra cómo los cambios en la variable original se reflejan a través del objeto de configuración.

Incluye tu archivo de cabecera en main.cpp usando #include "GameConfig.h".

Hoja de referencia

Una lista de inicialización de miembros es la forma preferida de inicializar los miembros de una clase en C++. Aparece después de la lista de parámetros del constructor, comenzando con dos puntos, con cada miembro inicializado directamente:

class Rectangle {
    int width;
    int height;
public:
    Rectangle(int w, int h) : width(w), height(h) {
        // Cuerpo del constructor
    }
};

¿Por qué usar listas de inicialización? Los miembros se construyen directamente con los valores correctos en lugar de ser construidos por defecto y luego asignados, lo que lo hace más eficiente.

Requerido para ciertos miembros:

  • Miembros const: no se pueden asignar después de la construcción
  • Miembros de referencia: deben vincularse en la inicialización
  • Miembros sin constructores por defecto
class Player {
    const int maxHealth;
    int& reference;
public:
    // Correcto - usa lista de inicialización
    Player(int max, int& r) : maxHealth(max), reference(r) {}
    
    // Error - no se puede asignar const o referencia en el cuerpo
    // Player(int max) { maxHealth = max; }
};

Importante: Los miembros se inicializan en el orden en que se declaran en la clase, no en el orden de la lista de inicialización. Escriba siempre su lista de inicialización en el orden de declaración.

Pruébalo tú mismo

#include <iostream>
#include <string>
#include "GameConfig.h"

using namespace std;

int main() {
    // Leer los valores de entrada
    string gameName;
    getline(cin, gameName);
    
    int maxPlayers;
    cin >> maxPlayers;
    
    int difficulty;
    cin >> difficulty;
    
    int width;
    cin >> width;
    
    int height;
    cin >> height;
    
    // TODO: Crear un objeto GameConfig usando el constructor de lista de inicialización
    // El constructor debe recibir: gameName, maxPlayers, difficulty (por referencia), width, height
    
    // TODO: Llamar a display() para mostrar la configuración inicial
    
    // TODO: Modificar la variable difficulty directamente (multiplicarla por 2)
    
    // TODO: Imprimir "After difficulty change:"
    
    // TODO: Llamar a display() de nuevo para mostrar la configuración actualizada
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos