다중 상속
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 53번째.
C++에서는 클래스가 여러 기본 클래스를 동시에 상속할 수 있습니다. 이를 다중 상속이라고 하며, 서로 다른 클래스 계층 구조의 기능을 결합할 수 있게 해 줍니다.
여러 클래스를 상속하려면 쉼표로 구분하세요:
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();
}
};이제 MultiFunctionDevice 클래스는 Printer와 Scanner의 메서드에 모두 접근할 수 있습니다.
MultiFunctionDevice mfd;
mfd.print(); // Printer에서 가져온 메서드
mfd.scan(); // Scanner에서 가져온 메서드
mfd.copy(); // 자체 메서드생성자는 상속 선언에 나열된 기본 클래스의 순서대로(왼쪽에서 오른쪽으로) 호출되고, 소멸자는 역순으로 호출됩니다. 초기화 목록에서 각 기본 클래스 생성자에 인수를 전달할 수 있습니다.
class MultiFunctionDevice : public Printer, public Scanner {
public:
MultiFunctionDevice() : Printer(), Scanner() {}
};두 기본 클래스에 같은 이름의 멤버가 있으면 잠재적인 문제가 발생합니다. 이로 인해 모호성이 생기므로, 어느 멤버를 뜻하는지 지정하려면 범위 지정 연산자를 사용해야 합니다.
class A { public: void show() {} };
class B { public: void show() {} };
class C : public A, public B {};
C obj;
obj.A::show(); // A의 버전을 호출
obj.B::show(); // B의 버전을 호출다중 상속은 강력하지만, 특히 기본 클래스들이 공통 조상을 공유할 때 복잡한 상황을 초래할 수 있습니다. 다음 강의에서 이 문제를 살펴보겠습니다.
챌린지
쉬움다중 상속을 사용해 여러 기본 클래스의 기능을 결합하는 스마트 홈 기기 시스템을 만들어 봅시다. WiFi에 연결하고 음성으로 제어할 수 있는 기기를 만든 다음, 이러한 기능을 하나의 스마트 스피커로 결합합니다.
코드를 세 개의 파일로 구성합니다.
WiFiDevice.h: 네트워크에 연결할 수 있는 모든 기기를 나타내는WiFiDevice클래스를 정의합니다.- 보호된
std::string networkName멤버 - 네트워크 이름을 받아 저장하는 생성자
Connecting to WiFi: <networkName>을 출력하는 공개connect()메서드WiFi Status: Connected을 출력하는 공개status()메서드
- 보호된
VoiceControl.h: 음성 기능이 있는 모든 기기를 나타내는VoiceControl클래스를 정의합니다.- 보호된
std::string assistantName멤버 - 음성 비서 이름을 받아 저장하는 생성자
<assistantName> is listening...을 출력하는 공개listen()메서드Voice Status: Active을 출력하는 공개status()메서드
- 보호된
main.cpp: 세 가지 입력을 읽습니다(각 입력은 별도의 줄에 입력).- 기기 이름(문자열)
- WiFi 네트워크 이름(문자열)
- 음성 비서 이름(문자열)
WiFiDevice와VoiceControl을 모두 공개 상속하는SmartSpeaker클래스를 정의합니다.- 비공개
std::string deviceName멤버 - 세 매개변수를 모두 받는 생성자. 초기화 목록을 사용해 네트워크 이름을
WiFiDevice에, 음성 비서 이름을VoiceControl에 전달하고 기기 이름을 저장합니다. <deviceName> powering on...을 출력한 다음connect()와listen()을 호출하는powerOn()메서드- 기기 이름을 출력한 다음 범위 지정 연산자를 사용해 두
status()메서드를 모두 호출하여 모호성을 해결하는showAllStatus()메서드
입력값으로
SmartSpeaker객체를 만듭니다.powerOn()을 호출하고 빈 줄을 출력한 다음showAllStatus()를 호출합니다.
예를 들어 입력값이 Echo, HomeNetwork, Alexa인 경우:
Echo powering on...
Connecting to WiFi: HomeNetwork
Alexa is listening...
Echo Status:
WiFi Status: Connected
Voice Status: ActiveshowAllStatus() 메서드는 한 줄에 기기 이름과 " Status:"를 출력한 다음, 두 기본 클래스에 이름이 같은 메서드가 있어 모호성이 발생하지 않도록 WiFiDevice::status()와 VoiceControl::status()를 사용해 각 기본 클래스의 status() 메서드를 호출해야 합니다.
직접 해보기
#include <iostream>
#include <string>
#include "WiFiDevice.h"
#include "VoiceControl.h"
using namespace std;
// TODO: WiFiDevice와 VoiceControl을 모두 public으로 상속하는 SmartSpeaker 클래스를 정의하세요
// - private 멤버: deviceName (string)
// - 생성자: deviceName, networkName, assistantName을 받습니다
// 초기화 목록을 사용하여 networkName을 WiFiDevice에, assistantName을 VoiceControl에 전달하세요
// - powerOn() 메서드: "<deviceName> powering on..."을 출력한 다음 connect()와 listen()을 호출합니다
// - showAllStatus() 메서드: "<deviceName> Status:"를 출력한 다음 두 status() 메서드를 모두 호출합니다
// 범위 지정 연산자를 사용하세요 (WiFiDevice::status()와 VoiceControl::status())
class SmartSpeaker {
// TODO: 여기에 SmartSpeaker 클래스를 구현하세요
};
int main() {
string deviceName, networkName, assistantName;
getline(cin, deviceName);
getline(cin, networkName);
getline(cin, assistantName);
// TODO: 입력값으로 SmartSpeaker 객체를 생성하세요
// TODO: powerOn()을 호출하세요
// TODO: 빈 줄을 출력하세요
// TODO: showAllStatus()를 호출하세요
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러