Menu
CoddyTech

Héritage multiple

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

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

Pour hériter de plusieurs classes, sépare-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 maintenant accès aux méthodes de Printer et de Scanner :

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

Les constructeurs sont appelés dans l’ordre dans lequel les classes de base sont listées dans la déclaration d’héritage (de gauche à droite), et les destructeurs dans l’ordre inverse. Tu peux transmettre 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 ont un membre portant le même nom. Cela crée une ambiguïté, et tu dois utiliser l’opérateur de résolution de portée pour préciser lequel tu veux désigner :

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 peut entraîner des situations complexes, surtout lorsque des classes de base partagent un ancêtre commun. Nous explorerons ce défi dans la prochaine leçon.

challenge icon

Défi

Facile

Créons un système d’appareils domotiques qui combine les fonctionnalités de plusieurs classes de base grâce à l’héritage multiple. Tu vas créer des appareils qui peuvent se connecter au WiFi et être commandés par la voix, puis combiner ces fonctionnalités dans une enceinte connectée unifiée.

Tu vas organiser ton code dans trois fichiers :

  • WiFiDevice.h : définis une classe WiFiDevice qui représente tout appareil capable de se connecter à un réseau :
    • Un membre protégé std::string networkName
    • Un constructeur qui prend un nom de réseau et l’enregistre
    • Une méthode publique connect() qui affiche : Connecting to WiFi: <networkName>
    • Une méthode publique status() qui affiche : WiFi Status: Connected
  • VoiceControl.h : définis une classe VoiceControl qui représente tout appareil doté de fonctionnalités vocales :
    • Un membre protégé std::string assistantName
    • Un constructeur qui prend le nom d’un assistant et l’enregistre
    • Une méthode publique listen() qui affiche : <assistantName> is listening...
    • Une méthode publique status() qui affiche : Voice Status: Active
  • main.cpp : lis 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éfinis une classe SmartSpeaker qui hérite publiquement à la fois de WiFiDevice et de VoiceControl :

    • Un membre privé std::string deviceName
    • Un constructeur qui prend 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 enregistre 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 lever l’ambiguïté

    Crée un objet SmartSpeaker avec les valeurs saisies. Appelle powerOn(), affiche une ligne vide, puis appelle 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 de VoiceControl::status() pour éviter toute ambiguïté, car 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 de VoiceControl
// - Membre privé : deviceName (string)
// - Constructeur : prend deviceName, networkName et assistantName
//   Utiliser la liste d’initialisation pour transmettre 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 saisies
    // 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