Menu
Coddy logo textTech

Héritage multiple

Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 53 sur 104.

Le C++ permet à une classe d'hériter de plusieurs classes de base simultanément. C'est ce qu'on appelle l'héritage multiple et cela vous permet de combiner des fonctionnalités provenant de différentes hiérarchies de classes.

Pour hériter de plusieurs classes, séparez-les par des virgules :

class Printer {
public:
    void print() {
        std::cout << "Printing document" << std::endl;
    }
};

class Scanner {
public:
    void scan() {
        std::cout << "Scanning document" << std::endl;
    }
};

class MultiFunctionDevice : public Printer, public Scanner {
public:
    void copy() {
        scan();
        print();
    }
};

La classe MultiFunctionDevice a désormais accès aux méthodes de Printer et de Scanner :

MultiFunctionDevice mfd;
mfd.print();  // Depuis Printer
mfd.scan();   // Depuis Scanner
mfd.copy();   // Sa propre méthode

Les constructeurs sont appelés dans l'ordre où les classes de base sont listées dans la déclaration d'héritage (de gauche à droite), et les destructeurs dans l'ordre inverse. Vous pouvez passer des arguments à chaque constructeur de base dans la liste d'initialisation :

class MultiFunctionDevice : public Printer, public Scanner {
public:
    MultiFunctionDevice() : Printer(), Scanner() {}
};

Un problème potentiel survient lorsque les deux classes de base possèdent un membre portant le même nom. Cela crée une ambiguïté, et vous devez utiliser l'opérateur de résolution de portée pour spécifier celui que vous visez :

class A { public: void show() {} };
class B { public: void show() {} };
class C : public A, public B {};

C obj;
obj.A::show();  // Appeler la version de A
obj.B::show();  // Appeler la version de B

L'héritage multiple est puissant, mais il peut mener à des situations complexes, particulièrement lorsque les classes de base partagent un ancêtre commun. Nous explorerons ce défi dans la prochaine leçon.

challenge icon

Défi

Facile

Construisons un système d'appareils domestiques intelligents qui combine les fonctionnalités de plusieurs classes de base à l'aide de l'héritage multiple. Vous allez créer des appareils qui peuvent à la fois se connecter au WiFi et être contrôlés par la voix, puis combiner ces fonctionnalités dans une enceinte intelligente unifiée.

Vous organiserez votre code sur trois fichiers :

  • WiFiDevice.h : définir une classe WiFiDevice qui représente tout appareil capable de se connecter à un réseau :
    • Un membre std::string networkName protégé
    • Un constructeur qui reçoit un nom de réseau et le stocke
    • Une méthode publique connect() qui affiche : Connecting to WiFi: <networkName>
    • Une méthode publique status() qui affiche : WiFi Status: Connected
  • VoiceControl.h : définir une classe VoiceControl qui représente tout appareil doté de fonctionnalités vocales :
    • Un membre std::string assistantName protégé
    • Un constructeur qui reçoit un nom d'assistant et le stocke
    • Une méthode publique listen() qui affiche : <assistantName> is listening...
    • Une méthode publique status() qui affiche : Voice Status: Active
  • main.cpp : lire trois entrées (chacune sur une ligne distincte) :
    1. Nom de l'appareil (chaîne de caractères)
    2. Nom du réseau WiFi (chaîne de caractères)
    3. Nom de l'assistant vocal (chaîne de caractères)

    Définir une classe SmartSpeaker qui hérite publiquement à la fois de WiFiDevice et de VoiceControl :

    • Un membre std::string deviceName privé
    • Un constructeur qui reçoit les trois paramètres, transmet le nom du réseau à WiFiDevice et le nom de l'assistant à VoiceControl à l'aide de la liste d'initialisation, puis stocke le nom de l'appareil
    • Une méthode powerOn() qui affiche : <deviceName> powering on..., puis appelle connect() et listen()
    • Une méthode showAllStatus() qui affiche le nom de l'appareil, puis utilise l'opérateur de résolution de portée pour appeler les deux méthodes status() afin de résoudre l'ambiguïté

    Créer un objet SmartSpeaker avec les valeurs saisies. Appeler powerOn(), afficher une ligne vide, puis appeler showAllStatus().

Par exemple, avec les entrées Echo, HomeNetwork et Alexa :

Echo powering on...
Connecting to WiFi: HomeNetwork
Alexa is listening...

Echo Status:
WiFi Status: Connected
Voice Status: Active

La méthode showAllStatus() doit afficher le nom de l'appareil suivi de " Status:" sur une ligne, puis appeler la méthode status() de chaque classe de base à l'aide de WiFiDevice::status() et VoiceControl::status() pour éviter toute ambiguïté, puisque les deux classes de base possèdent une méthode portant le même nom.

Essayez vous-même

#include <iostream>
#include <string>
#include "WiFiDevice.h"
#include "VoiceControl.h"

using namespace std;

// TODO: Définir la classe SmartSpeaker qui hérite publiquement de WiFiDevice et VoiceControl
// - Membre privé : deviceName (string)
// - Constructeur : prend deviceName, networkName, assistantName
//   Utiliser la liste d'initialisation pour passer networkName à WiFiDevice et assistantName à VoiceControl
// - Méthode powerOn() : affiche "<deviceName> powering on...", puis appelle connect() et listen()
// - Méthode showAllStatus() : affiche "<deviceName> Status:", puis appelle les deux méthodes status()
//   en utilisant la résolution de portée (WiFiDevice::status() et VoiceControl::status())

class SmartSpeaker {
    // TODO: Implémenter la classe SmartSpeaker ici
};

int main() {
    string deviceName, networkName, assistantName;
    getline(cin, deviceName);
    getline(cin, networkName);
    getline(cin, assistantName);

    // TODO: Créer un objet SmartSpeaker avec les valeurs d'entrée
    // TODO: Appeler powerOn()
    // TODO: Afficher une ligne vide
    // TODO: Appeler showAllStatus()

    return 0;
}
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur C++ en ligne