728x90

황기태 저자의 명품 C++ Programming 개정판을 읽고 학습한 내용을 정리한 포스트입니다!

https://search.shopping.naver.com/book/catalog/32436115747

 

C++ Programming : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 

요즘 시대는 융합 혹은 컨버전스(convergence)의 시대이다. 무선 전화기와 MP3의 기능을합친 제품들처럼 각 기능을 모듈화하고 여러 모듈을 조립하면 융합된 새로운 형태의 제품이 만들어진다.

SW의 경우에도 다르지 않다. 모듈화를 통해 코드를 재사용하는 것이 대세이며, C++에서는 코드를 클래스로 모듈화하고 상속을 통해 기능을 확장한다. 


다중 상속

  • 하나의 파생 클래스가 여러 클래스를 동시에 상속받는 것
  • 다중 상속으로 파생 클래스를 선언할 때는 클래스 선언문에서 접근 지정과 함께 기본 클래스를 콤마(,)로 나열하면 된다.
class MP3 {
public:
	void play();
	void stop();
};

class MobilePhone {
public:
	bool sendCall();
	bool receiveCall();
	bool sendSMS();
	bool receiveSMS();
};

class MusicPhone : public MP3, public MobilePhone { // 다중 상속 선언
public:
	void dial();
};

 

다중 상속 활용
void MusicPhone : dial() {
	play(); // mp3 실행
	sendCall(); // 전화 걸기
}
  • 또한 다른 클래스나 외부 함수에서 MusicPhone이 다중 상속받은 멤버들을 다음과 같이 호출할 수 있다.
int main() {
	MusicPhone hanPhone;
	hanPhone.play();
	hanPhone.sendSMS();
}

 

가상 상속

다중상속의 문제점 
  • 클래스의 재사용과 코딩의 효율을 높이는 장점이 있는 반면, 보이지 않는 문제가 있다.

  • BaseIO, In, Out을 다중 상속 받은 InOut 클래스가 있다.
  • InOut ioObj를 생성 시 safe 변수 공간이 배정되고, 기본 클래스 In의 readPos 변수 공간이 배정, 다시 BaseIO 클래스의 mode 변수 공간이 배정 된다.
  • 또한 Out 클래스도 상속받기에 Out 클래스의 writePos 변수 공간이 배정되고, Out 기본 클래스 BaseIO의 mode 변수 공간이 배정된다.
  • 그렇기에 ioObj.mode로 접근시 mode 공간이 2개가 생성되어 있어 컴파일 오류가 발생한다.
    • 컴파일러는 중복 상속되어 생긴 mode 중 어떤 mode 인지 판단할 수 없기에 발생한다.

 

가상 상속
  • 멤버 중복 생성 문제를 해결하기 위해선, virtual 키워드를 이용하여 가상 상속을 선언하면 된다.
class In : virtual public BaseIO {
 ...
};

class Out : virtual public BaseIO {
 ...
};

 

  • 이 때, In과 Out은 '가상 기본 클래스(virtual base class) BaseIO를 상속 받는다'라고 하거나 BaseIO를 '가상 상속 받는다'라고 한다.
  • virtual 키워드는 컴파일러에게 파생 클래스의 객체가 생성될 때 기본 클래스의 멤버 공간을 오직 한 번만 할당하고, 이미 할당되어 있다면 그 공간을 공유하도록 지시한다.
가상 상속 사례 : C++ 표준 라이브러리
  • 기본 클래스를 가상 상속받는 경우는 C++ 표준 클래스 라이브러리에도 종종 볼 수 있다.
  • ios 클래스를 istream과 ostream이 상속받고, iostream이 istream과 ostream을 다중 상속받는 경우로서, istream과 ostream이 ios를 다음과 같이 가상 상속받아 다중 상속의 모호성 문제를 해결한다.
class istream : virtual public ios { ... };
class ostream : virtual public ios { ... };
class iostream : public istream, public ostream { ... };
728x90

'Programming Language > C++' 카테고리의 다른 글

[C++] 오버라이딩  (0) 2023.12.18
[C++] 가상 함수와 오버라이딩  (1) 2023.12.18
[C++] public, protected, private 상속  (0) 2023.12.14
[C++] 상속과 생성자, 소멸자  (1) 2023.12.14
[C++] protected 접근 지정  (0) 2023.12.14