Constructeurs délégués
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 23 sur 104.
Lorsque vous avez plusieurs constructeurs qui partagent une logique d'initialisation commune, vous pouvez utiliser des constructeurs délégués pour éviter la duplication de code. Un constructeur délégué appelle un autre constructeur de la même classe dans sa liste d'initialisation.
class Player {
std::string name;
int health;
int level;
public:
// Constructeur principal - effectue le travail réel
Player(std::string n, int h, int lvl)
: name(n), health(h), level(lvl) {}
// Délègue au constructeur principal
Player(std::string n) : Player(n, 100, 1) {}
// Le constructeur par défaut délègue également
Player() : Player("Unknown") {}
};La délégation se produit dans la liste d'initialisation en utilisant le nom de la classe suivi des arguments. Lorsque Player() est appelé, il délègue à Player(std::string), qui délègue ensuite au constructeur à trois paramètres. La chaîne s'exécute du constructeur cible vers l'original.
Il y a une règle importante : un constructeur de délégation ne peut pas avoir d'autres membres dans sa liste d'initialisation. La délégation doit être le seul élément :
class Item {
int id;
int value;
public:
Item(int i, int v) : id(i), value(v) {}
// Erreur ! Impossible de mélanger la délégation avec l'initialisation des membres
// Item(int i) : Item(i, 0), id(i) {}
// Correct - délégation uniquement
Item(int i) : Item(i, 0) {}
};Les constructeurs délégués aident à centraliser la logique d'initialisation en un seul endroit, rendant votre code plus facile à maintenir et moins sujet aux erreurs dues à la duplication de code.
Défi
FacileConstruisons un système de paramètres de connexion qui démontre comment les constructeurs délégués peuvent éliminer la duplication de code en enchaînant les appels de constructeurs.
Vous allez créer deux fichiers pour organiser votre code :
Connection.h: Définissez une classeConnectionqui représente une connexion réseau avec diverses options de configuration. Votre classe doit avoir :- Membres privés :
host(string),port(int),timeout(int en secondes), etsecure(bool) - Un constructeur primaire qui prend les quatre paramètres et initialise tous les membres à l'aide d'une liste d'initialisation. Ce constructeur doit afficher
"Connection configured: <host>:<port>" - Un constructeur prenant uniquement
hostetportqui délègue au constructeur primaire avectimeoutpar défaut à30etsecurepar défaut àfalse - Un constructeur prenant uniquement
hostqui délègue au constructeur à deux paramètres avecportpar défaut à80 - Un constructeur par défaut qui délègue au constructeur à un paramètre avec
hostpar défaut à"localhost" - Une méthode
getInfo()qui retourne une chaîne de caractères au format :"<host>:<port> (timeout: <timeout>s, secure: <yes/no>)"
- Membres privés :
main.cpp: Démontrez la chaîne de délégation en créant des connexions à l'aide de différents constructeurs. Lisez un nom d'hôte (host) et un numéro de port depuis l'entrée (chacun sur une ligne séparée), puis :- Créez une
Connectionen utilisant le constructeur par défaut - Créez une
Connectionen utilisant uniquement le host provenant de l'entrée - Créez une
Connectionen utilisant à la fois le host et le port provenant de l'entrée - Créez une
Connectionavec le host d'entrée, le port d'entrée, un timeout de60, et secure défini surtrue - Affichez
getInfo()pour chaque connexion, une par ligne
- Créez une
La chaîne de délégation fonctionne ainsi : le constructeur par défaut appelle le constructeur à un paramètre, qui appelle le constructeur à deux paramètres, qui appelle le constructeur primaire à quatre paramètres. Cela signifie que le message "Connection configured" s'affiche une fois pour chaque objet créé, toujours à partir du constructeur primaire.
Pour le statut de sécurité dans getInfo(), affichez "yes" si secure est vrai, sinon "no".
Incluez votre fichier d'en-tête dans main.cpp en utilisant #include "Connection.h".
Aide-mémoire
Un constructeur délégué appelle un autre constructeur de la même classe dans sa liste d'initialisation pour éviter la duplication de code :
class Player {
std::string name;
int health;
int level;
public:
// Constructeur principal
Player(std::string n, int h, int lvl)
: name(n), health(h), level(lvl) {}
// Délègue au constructeur principal
Player(std::string n) : Player(n, 100, 1) {}
// Le constructeur par défaut délègue également
Player() : Player("Unknown") {}
};La délégation se produit dans la liste d'initialisation en utilisant le nom de la classe suivi des arguments. Les constructeurs peuvent former une chaîne de délégation où l'un délègue à un autre.
Règle importante : Un constructeur délégué ne peut pas avoir d'autres membres dans sa liste d'initialisation. La délégation doit être le seul élément :
class Item {
int id;
int value;
public:
Item(int i, int v) : id(i), value(v) {}
// Erreur ! Impossible de mélanger la délégation avec l'initialisation des membres
// Item(int i) : Item(i, 0), id(i) {}
// Correct - délégation uniquement
Item(int i) : Item(i, 0) {}
};Essayez vous-même
#include <iostream>
#include <string>
#include "Connection.h"
using namespace std;
int main() {
// Lire l'entrée
string host;
int port;
cin >> host;
cin >> port;
// TODO: Créer une Connection en utilisant le constructeur par défaut
// TODO: Créer une Connection en utilisant uniquement le host de l'entrée
// TODO: Créer une Connection en utilisant à la fois le host et le port de l'entrée
// TODO: Créer une Connection avec le host d'entrée, le port d'entrée, timeout=60, secure=true
// TODO: Afficher getInfo() pour chaque connexion, une par ligne
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique