Costruttori deleganti
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 23 di 104.
Quando hai più costruttori che condividono una logica di inizializzazione comune, puoi usare i costruttori deleganti per evitare la duplicazione del codice. Un costruttore delegante chiama un altro costruttore della stessa classe nella sua lista di inizializzazione.
class Player {
std::string name;
int health;
int level;
public:
// Costruttore principale - svolge il lavoro effettivo
Player(std::string n, int h, int lvl)
: name(n), health(h), level(lvl) {}
// Delega al costruttore principale
Player(std::string n) : Player(n, 100, 1) {}
// Anche il costruttore predefinito delega
Player() : Player("Unknown") {}
};La delega avviene nella lista di inizializzazione usando il nome della classe seguito dagli argomenti. Quando viene chiamato Player(), delega a Player(std::string), che a sua volta delega al costruttore con tre parametri. La catena viene eseguita dal costruttore di destinazione fino a quello originale.
C'è una regola importante: un costruttore delegante non può avere altri membri nella sua lista di inizializzazione. La delega deve essere l'unico elemento:
class Item {
int id;
int value;
public:
Item(int i, int v) : id(i), value(v) {}
// Errore! Non è possibile combinare la delega con l'inizializzazione dei membri
// Item(int i) : Item(i, 0), id(i) {}
// Corretto: solo delega
Item(int i) : Item(i, 0) {}
};I costruttori deleganti aiutano a centralizzare la logica di inizializzazione in un unico punto, rendendo il codice più facile da mantenere e meno soggetto a errori dovuti alla duplicazione del codice.
Sfida
FacileCreiamo un sistema di impostazioni di connessione che dimostri come i costruttori deleganti possano eliminare la duplicazione del codice concatenando le chiamate ai costruttori.
Creerai due file per organizzare il codice:
Connection.h: definisci una classeConnectionche rappresenta una connessione di rete con varie opzioni di configurazione. La classe deve avere:- Membri privati:
host(stringa),port(int),timeout(int in secondi) esecure(bool) - Un costruttore principale che accetta tutti e quattro i parametri e inizializza tutti i membri usando una lista di inizializzazione. Questo costruttore deve stampare
"Connection configured: <host>:<port>" - Un costruttore che accetta solo
hosteporte delega al costruttore principale, impostandotimeoutsu30esecuresufalsecome valori predefiniti - Un costruttore che accetta solo
hoste delega al costruttore con due parametri, impostandoportsu80come valore predefinito - Un costruttore predefinito che delega al costruttore con un parametro, impostando
hostsu"localhost"come valore predefinito - Un metodo
getInfo()che restituisce una stringa nel formato:"<host>:<port> (timeout: <timeout>s, secure: <yes/no>)"
- Membri privati:
main.cpp: mostra la catena di delega creando connessioni con diversi costruttori. Leggi dall'input un nome host e un numero di porta (ciascuno su una riga separata), poi:- Crea una
Connectionusando il costruttore predefinito - Crea una
Connectionusando solo l'host dell'input - Crea una
Connectionusando sia l'host sia la porta dell'input - Crea una
Connectioncon l'host dell'input, la porta dell'input, un timeout di60e secure impostato sutrue - Stampa
getInfo()per ciascuna connessione, una per riga
- Crea una
La catena di delega funziona così: il costruttore predefinito chiama il costruttore con un parametro, che chiama quello con due parametri, che a sua volta chiama il costruttore principale con quattro parametri. Ciò significa che il messaggio "Connection configured" viene stampato una volta per ogni oggetto creato, sempre dal costruttore principale.
Per lo stato di sicurezza in getInfo(), stampa "yes" se secure è true, altrimenti "no".
Includi il file header in main.cpp usando #include "Connection.h".
Provalo tu
#include <iostream>
#include <string>
#include "Connection.h"
using namespace std;
int main() {
// Leggi l'input
string host;
int port;
cin >> host;
cin >> port;
// TODO: Crea una Connection usando il costruttore predefinito
// TODO: Crea una Connection usando solo host dall'input
// TODO: Crea una Connection usando sia host sia port dall'input
// TODO: Crea una Connection con host e port dall'input, timeout=60 e secure=true
// TODO: Stampa getInfo() per ogni connessione, una per riga
return 0;
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore genericoEsercitati da solo: Compilatore C++ online