Menu
Coddy logo textTech

Construtores Delegados

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 23 de 104.

Quando você tem múltiplos construtores que compartilham uma lógica de inicialização comum, você pode usar construtores delegados para evitar a duplicação de código. Um construtor delegado chama outro construtor da mesma classe em sua lista de inicialização.

class Player {
    std::string name;
    int health;
    int level;
public:
    // Construtor primário - faz o trabalho real
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Delega para o construtor primário
    Player(std::string n) : Player(n, 100, 1) {}
    
    // Construtor padrão também delega
    Player() : Player("Unknown") {}
};

A delegação ocorre na lista de inicializadores usando o nome da classe seguido pelos argumentos. Quando Player() é chamado, ele delega para Player(std::string), que então delega para o construtor de três parâmetros. A cadeia é executada do construtor de destino de volta ao original.

Existe uma regra importante: um construtor delegante não pode ter outros membros em sua lista de inicialização. A delegação deve ser o único item:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // Erro! Não é possível misturar delegação com inicialização de membros
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Correto - apenas delegação
    Item(int i) : Item(i, 0) {}
};

Construtores delegados ajudam a centralizar a lógica de inicialização em um só lugar, tornando seu código mais fácil de manter e menos propenso a erros decorrentes de código duplicado.

challenge icon

Desafio

Fácil

Vamos construir um sistema de configurações de conexão que demonstra como os construtores delegados podem eliminar a duplicação de código ao encadear chamadas de construtores.

Você criará dois arquivos para organizar seu código:

  • Connection.h: Defina uma classe Connection que representa uma conexão de rede com várias opções de configuração. Sua classe deve ter:
    • Membros privados: host (string), port (int), timeout (int em segundos) e secure (bool)
    • Um construtor primário que recebe todos os quatro parâmetros e inicializa todos os membros usando uma lista de inicialização. Este construtor deve imprimir "Connection configured: <host>:<port>"
    • Um construtor que recebe apenas host e port que delega para o construtor primário com timeout padrão de 30 e secure padrão de false
    • Um construtor que recebe apenas host que delega para o construtor de dois parâmetros com port padrão de 80
    • Um construtor padrão que delega para o construtor de um parâmetro com host padrão de "localhost"
    • Um método getInfo() que retorna uma string no formato: "<host>:<port> (timeout: <timeout>s, secure: <yes/no>)"
  • main.cpp: Demonstre a cadeia de delegação criando conexões usando diferentes construtores. Leia um nome de host e um número de porta da entrada (cada um em uma linha separada) e, em seguida:
    • Crie uma Connection usando o construtor padrão
    • Crie uma Connection usando apenas o host da entrada
    • Crie uma Connection usando tanto o host quanto a porta da entrada
    • Crie uma Connection com o host da entrada, a porta da entrada, timeout de 60 e secure definido como true
    • Imprima getInfo() para cada conexão, uma por linha

A cadeia de delegação flui assim: o construtor padrão chama o construtor de um parâmetro, que chama o construtor de dois parâmetros, que chama o construtor primário de quatro parâmetros. Isso significa que a mensagem "Connection configured" é impressa uma vez para cada objeto criado, sempre a partir do construtor primário.

Para o status de segurança em getInfo(), imprima "yes" se secure for true, caso contrário, imprima "no".

Inclua seu arquivo de cabeçalho no main.cpp usando #include "Connection.h".

Folha de consulta

Um construtor delegador chama outro construtor da mesma classe em sua lista de inicialização para evitar a duplicação de código:

class Player {
    std::string name;
    int health;
    int level;
public:
    // Construtor primário
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Delega para o construtor primário
    Player(std::string n) : Player(n, 100, 1) {}
    
    // O construtor padrão também delega
    Player() : Player("Unknown") {}
};

A delegação ocorre na lista de inicialização usando o nome da classe seguido pelos argumentos. Os construtores podem formar uma cadeia de delegação onde um delega para outro.

Regra importante: Um construtor delegador não pode ter outros membros em sua lista de inicialização. A delegação deve ser o único item:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // Erro! Não é possível misturar delegação com inicialização de membros
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Correto - apenas delegação
    Item(int i) : Item(i, 0) {}
};

Experimente você mesmo

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

using namespace std;

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

    // TODO: Criar uma Connection usando o construtor padrão

    // TODO: Criar uma Connection usando apenas o host da entrada

    // TODO: Criar uma Connection usando tanto o host quanto o port da entrada

    // TODO: Criar uma Connection com o host da entrada, port da entrada, timeout=60, secure=true

    // TODO: Imprimir getInfo() para cada conexão, uma por linha

    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos