Menu
Coddy logo textTech

Herança múltipla

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 53 de 104.

O C++ permite que uma classe herde de múltiplas classes base simultaneamente. Isso é chamado de herança múltipla e permite combinar recursos de diferentes hierarquias de classes.

Para herdar de múltiplas classes, separe-as com vírgulas:

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();
    }
};

A classe MultiFunctionDevice agora tem acesso a métodos de ambos Printer e Scanner:

MultiFunctionDevice mfd;
mfd.print();  // De Printer
mfd.scan();   // De Scanner
mfd.copy();   // Seu próprio método

Os construtores são chamados na ordem em que as classes base são listadas na declaração de herança (da esquerda para a direita), e os destrutores na ordem inversa. Você pode passar argumentos para cada construtor base na lista de inicialização:

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

Um problema potencial surge quando ambas as classes base possuem um membro com o mesmo nome. Isso cria ambiguidade, e você deve usar o operador de resolução de escopo para especificar qual deles você se refere:

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

C obj;
obj.A::show();  // Chama a versão de A
obj.B::show();  // Chama a versão de B

Herança múltipla é poderosa, mas pode levar a situações complexas, especialmente quando as classes base compartilham um ancestral comum. Exploraremos esse desafio na próxima aula.

challenge icon

Desafio

Fácil

Vamos criar um sistema de dispositivos domésticos inteligentes que combine recursos de várias classes-base usando herança múltipla. Você criará dispositivos que podem tanto se conectar ao WiFi quanto ser controlados por voz e, em seguida, combinará esses recursos em um alto-falante inteligente unificado.

Você organizará seu código em três arquivos:

  • WiFiDevice.h: Defina uma classe WiFiDevice que represente qualquer dispositivo capaz de se conectar a uma rede:
    • Um membro std::string networkName protegido
    • Um construtor que receba um nome de rede e o armazene
    • Um método público connect() que exiba: Connecting to WiFi: <networkName>
    • Um método público status() que exiba: WiFi Status: Connected
  • VoiceControl.h: Defina uma classe VoiceControl que represente qualquer dispositivo com recursos de voz:
    • Um membro std::string assistantName protegido
    • Um construtor que receba um nome de assistente e o armazene
    • Um método público listen() que exiba: <assistantName> is listening...
    • Um método público status() que exiba: Voice Status: Active
  • main.cpp: Leia três entradas (cada uma em uma linha separada):
    1. Nome do dispositivo (string)
    2. Nome da rede WiFi (string)
    3. Nome do assistente de voz (string)

    Defina uma classe SmartSpeaker que herde publicamente de WiFiDevice e VoiceControl:

    • Um membro std::string deviceName privado
    • Um construtor que receba os três parâmetros, passe o nome da rede para WiFiDevice e o nome do assistente para VoiceControl usando a lista de inicialização e armazene o nome do dispositivo
    • Um método powerOn() que exiba: <deviceName> powering on... e, em seguida, chame connect() e listen()
    • Um método showAllStatus() que exiba o nome do dispositivo e, em seguida, use o operador de resolução de escopo para chamar ambos os métodos status() e resolver a ambiguidade

    Crie um objeto SmartSpeaker com os valores de entrada. Chame powerOn(), exiba uma linha em branco e, em seguida, chame showAllStatus().

Por exemplo, com as entradas Echo, HomeNetwork e Alexa:

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

Echo Status:
WiFi Status: Connected
Voice Status: Active

O método showAllStatus() deve exibir o nome do dispositivo seguido por " Status:" em uma linha e, em seguida, chamar o método status() de cada classe-base usando WiFiDevice::status() e VoiceControl::status() para evitar a ambiguidade, já que ambas as classes-base têm um método com o mesmo nome.

Experimente você mesmo

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

using namespace std;

// TODO: Definir a classe SmartSpeaker que herda publicamente de WiFiDevice e VoiceControl
// - Membro privado: deviceName (string)
// - Construtor: recebe deviceName, networkName, assistantName
//   Use a lista de inicialização para passar networkName para WiFiDevice e assistantName para VoiceControl
// - Método powerOn(): imprime "<deviceName> powering on...", então chama connect() e listen()
// - Método showAllStatus(): imprime "<deviceName> Status:", então chama ambos os métodos status()
//   usando resolução de escopo (WiFiDevice::status() e VoiceControl::status())

class SmartSpeaker {
    // TODO: Implementar a classe SmartSpeaker aqui
};

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

    // TODO: Criar um objeto SmartSpeaker com os valores de entrada
    // TODO: Chamar powerOn()
    // TODO: Imprimir uma linha em branco
    // TODO: Chamar showAllStatus()

    return 0;
}
quiz iconTeste seus conhecimentos

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

Pratique por conta própria: Compilador de C++ online