Menu
Coddy logo textTech

Constructores delegados

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

Cuando tienes múltiples constructores que comparten una lógica de inicialización común, puedes usar constructores delegados para evitar la duplicación de código. Un constructor delegado llama a otro constructor de la misma clase en su lista de inicializadores.

class Player {
    std::string name;
    int health;
    int level;
public:
    // Constructor primario - realiza el trabajo real
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Delega en el constructor primario
    Player(std::string n) : Player(n, 100, 1) {}
    
    // El constructor por defecto también delega
    Player() : Player("Unknown") {}
};

La delegación ocurre en la lista de inicializadores utilizando el nombre de la clase seguido de los argumentos. Cuando se llama a Player(), esta delega en Player(std::string), el cual luego delega en el constructor de tres parámetros. La cadena se ejecuta desde el constructor de destino de vuelta al original.

Hay una regla importante: un constructor delegado no puede tener otros miembros en su lista de inicialización. La delegación debe ser el único elemento:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // ¡Error! No se puede mezclar la delegación con la inicialización de miembros
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Correcto - solo delegación
    Item(int i) : Item(i, 0) {}
};

Los constructores delegados ayudan a centralizar la lógica de inicialización en un solo lugar, lo que hace que su código sea más fácil de mantener y menos propenso a errores por código duplicado.

challenge icon

Desafío

Fácil

Construyamos un sistema de configuración de conexiones que demuestre cómo los constructores delegados pueden eliminar la duplicación de código encadenando las llamadas a los constructores.

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

  • Connection.h: Define una clase Connection que represente una conexión de red con varias opciones de configuración. Tu clase debe tener:
    • Miembros privados: host (string), port (int), timeout (int en segundos) y secure (bool)
    • Un constructor primario que tome los cuatro parámetros e inicialice todos los miembros usando una lista de inicialización. Este constructor debe imprimir "Connection configured: <host>:<port>"
    • Un constructor que tome solo host y port que delegue al constructor primario con timeout por defecto en 30 y secure por defecto en false
    • Un constructor que tome solo host que delegue al constructor de dos parámetros con port por defecto en 80
    • Un constructor por defecto que delegue al constructor de un parámetro con host por defecto en "localhost"
    • Un método getInfo() que devuelva un string con el formato: "<host>:<port> (timeout: <timeout>s, secure: <yes/no>)"
  • main.cpp: Demuestra la cadena de delegación creando conexiones usando diferentes constructores. Lee un nombre de host y un número de puerto de la entrada (cada uno en una línea separada), luego:
    • Crea una Connection usando el constructor por defecto
    • Crea una Connection usando solo el host de la entrada
    • Crea una Connection usando tanto el host como el puerto de la entrada
    • Crea una Connection con el host de entrada, el puerto de entrada, un timeout de 60 y secure establecido en true
    • Imprime getInfo() para cada conexión, una por línea

La cadena de delegación fluye así: el constructor por defecto llama al constructor de un parámetro, el cual llama al constructor de dos parámetros, el cual llama al constructor primario de cuatro parámetros. Esto significa que el mensaje "Connection configured" se imprime una vez por cada objeto creado, siempre desde el constructor primario.

Para el estado de seguridad en getInfo(), imprime "yes" si secure es true, de lo contrario imprime "no".

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

Hoja de referencia

Un constructor delegado llama a otro constructor de la misma clase en su lista de inicialización para evitar la duplicación de código:

class Player {
    std::string name;
    int health;
    int level;
public:
    // Constructor primario
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Delega en el constructor primario
    Player(std::string n) : Player(n, 100, 1) {}
    
    // El constructor por defecto también delega
    Player() : Player("Unknown") {}
};

La delegación ocurre en la lista de inicialización utilizando el nombre de la clase seguido de los argumentos. Los constructores pueden formar una cadena de delegación donde uno delega en otro.

Regla importante: Un constructor delegado no puede tener otros miembros en su lista de inicialización. La delegación debe ser el único elemento:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // ¡Error! No se puede mezclar la delegación con la inicialización de miembros
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Correcto - solo delegación
    Item(int i) : Item(i, 0) {}
};

Pruébalo tú mismo

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

using namespace std;

int main() {
    // Leer la entrada
    string host;
    int port;
    cin >> host;
    cin >> port;

    // TODO: Crear una Connection usando el constructor por defecto

    // TODO: Crear una Connection usando solo el host de la entrada

    // TODO: Crear una Connection usando tanto el host como el port de la entrada

    // TODO: Crear una Connection con el host de entrada, el port de entrada, timeout=60, secure=true

    // TODO: Imprimir getInfo() para cada conexión, una por línea

    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