Construtores Delegantes
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.
Desafio
FácilVamos criar um sistema de configurações de conexão que demonstra como construtores delegantes podem eliminar a duplicação de código encadeando chamadas de construtores.
Você criará dois arquivos para organizar seu código:
Connection.h: Defina uma classeConnectionque represente 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) esecure(bool) - Um construtor primário que receba os quatro parâmetros e inicialize todos os membros usando uma lista de inicialização. Esse construtor deve imprimir
"Connection configured: <host>:<port>" - Um construtor que receba apenas
hosteporte delegue ao construtor primário, comtimeoutassumindo o valor padrão30esecureassumindo o valor padrãofalse - Um construtor que receba apenas
hoste delegue ao construtor de dois parâmetros, comportassumindo o valor padrão80 - Um construtor padrão que delegue ao construtor de um parâmetro, com
hostassumindo o valor padrão"localhost" - Um método
getInfo()que retorne uma string no formato:"<host>:<port> (timeout: <timeout>s, secure: <yes/no>)"
- Membros privados:
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
Connectionusando o construtor padrão - Crie uma
Connectionusando apenas o host da entrada - Crie uma
Connectionusando o host e a porta da entrada - Crie uma
Connectioncom o host da entrada, a porta da entrada, timeout de60e secure definido comotrue - Imprima
getInfo()para cada conexão, uma por linha
- Crie uma
A cadeia de delegação funciona 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 seguro em getInfo(), imprima "yes" se secure for true; caso contrário, imprima "no".
Inclua seu arquivo de cabeçalho em main.cpp usando #include "Connection.h".
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;
}
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
1Fundamentos de POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner GenéricoPratique por conta própria: Compilador de C++ online