콘텐츠로 이동

Chapter 11. 상속

'명품 C++Programming - 황기태' 8장 학습 내용

소스코드

1절. 상속

2절. 파생 클래스

3절. 업 캐스팅과 다운 캐스팅

4절. 접근 상속 지정

5절. 생성자와 소멸자

6절. 다중 상속

7절. 가상 상속

1절. 상속

C++의 상속

  • 클래스 사이에서 상속 관계 정의
  • 객체 사이에는 상속 관계 없음
  • 기본 클래스의 속성과 기능을 파생 클래스에 물려줌
  • 기본 클래스(base class)
    • 상속해주는 클래스
    • 부모 클래스
  • 파생 클래스(derived class)
    • 상속받는 클래스
    • 자식 클래스
    • 기본 클래스의 속성과 기능을 물려받음
    • 자신만의 속성과 기능을 추가하여 작성
  • 기본 클래스에서 파생 클래스로 갈수록 클래스의 개념이 구체화
  • 다중 상속을 통한 클래스의 재활용성 증가

상속의 표현

inim

상속의 목적 및 장점

  • 간결한 클래스 작성
  • 기본 클래스의 기능을 물려받아 파생 클래스를 간결하게 작성
  • 클래스 간의 계층적 분류 및 관리의 용이
  • 상속은 클래스들의 구조적 관계 파악 용이
  • 클래스 재사용과 확장을 통한 소프트웨어 생산성 향상
  • 빠른 소프트웨어 생산 필요
  • 기존에 작성한 클래스의 재사용 : 상속
    • 상속받아 새로운 기능을 확장
  • 앞으로 있을 상속에 대비한 클래스의 객체 지향적 설계 필요

상속 관계로 클래스의 간결화 사례 예시

inclass

상속 선언

instudent

  • Student 클래스는 Person 클래스의 멤버를 물려받음
  • StudentWorker 클래스는 Student의 멤버를 물려받음

  • Student가 물려받은 Person의 멤버도 함께 물려받음

  • 예제 1. Point 클래스를 상속받는 ColorPoint 클래스 예제
    SourceCodeChecking

2절. 파생 클래스

파생 클래스의 객체 구성

po

cpo

파생 클래스에서 기본 클래스 멤버 접근

cpo2

외부에서 파생 클래스 객체에 대한 접근

cpo3

3절. 업 캐스팅과 다운 캐스팅

상속과 객체 포인터 : 업 캐스팅

  • 업 캐스팅(up - casting)
  • 파생 클래스 포인터가 기본 클래스 포인터에 치환
    • ex) 사람을 동물로 보는 것(사람은 동물 안에 속함)

upcasting

int main() {
 ColorPoint cp;
 ColorPoint *pDER = &cp;
 Point* pBase = pDer;
 // 업캐스팅

 pDer->set(3, 4);
 pBase->showPoint();
 pDer->setColor("Red");
 pDer->showColorPoint();
 pBase->showColorPoint();    // 컴파일 오류
}
// 출력 예시
// (3, 4)
// Red(3, 4)

상속과 객체 포인터 : 다운 캐스팅

  • 다운 캐스팅(down - casting)
  • 기본 클래스의 포인터가 파생 클래스의 포인터에 치환되는 것

downcasting

int main(){
 ColorPoint cp;
 ColorPoint *PDer;
 Point* pBase = &cp;
 // 업캐스팅

 pBase->set(3, 4);
 pBase->showPoint();

 pDer = (ColorPoint *)pBase;
 // 다운 캐스팅
 // 강제 타입 변환이 반드시 필요

 pDer->setColor("Red");
 pDer->showColorPoint();
 // 둘 다 정상 컴파일
}
// 출력 예시
// (3, 4)
// Red(3, 4)

업 캐스팅과 다운 캐스팅 이해하기

4절. 접근 상속 지정

접근 지정자

  • private 멤버
  • 선언된 클래스 내에서만 접근 가능
  • 파생 클래스에서도 기본 클래스의 private 멤버 직접 접근 불가
  • public 멤버
  • 선언된 클래스나 외부 어떤 클래스, 모든 외부 함수에 접근 허용
  • 파생 클래스에서 기본 클래스의 public 멤버 접근 가능
  • protected 멤버
  • 선언된 클래스에서 접근 가능
  • 파생된 클래스에서만 접근 허용
    • 파생 클래스가 아닌 다른 클래스, 혹은 외부 함수에서는 protected 멤버 접근 불가

멤버의 접근 지정에 따른 접근성

am

상속 지정

  • 상속 선언 시 public, private, protected의 3가지 중 하나 지정
  • 기본 클래스 멤버의 접근 속성을 어떻게 계승할 것인지 지정
  • public : 기본 클래스의 protected, public 멤버 속성을 그대로 계승
  • private : 기본 클래스의 protected, public 멤버를 private로 계승
  • protected : 기본 클래스의 protected, public 멤버를 protected로 계승

상속 시 접근 지정에 따른 멤버의 접근 지정 속성 변화

ppp

컴파일 오류 탐색 예제 3, 4, 5

5절. 생성자와 소멸자

상속 관계의 생성자와 소멸자

  • 파생 클래스의 객체가 생성될 때
  • 파생 클래스의 생성자와 기본 클래스의 생성자가 모두 실행
  • 기본 클래스의 생성자가 먼저 실행된 후 파생 클래스의 생성자 실행

생성자 호출 관계 및 실행 순서

con1

소멸자의 실행 순서

  • 파생 클래스의 객체가 생성될 때
  • 파생 클래스의 소멸자 먼저 실행
  • 기본 클래스의 소멸자가 나중에 실행

컴파일러에 의해 묵시적으로 기본 클래스의 생성자를 선택하는 경우

  • 파생 클래스의 생성자에서 기본 클래스의 기본 생성자 호출

basiccon

기본 클래스에 기본 생성자가 없는 경우 : 컴파일 오류

errorcon

매개 변수를 가진 파생 클래스의 생성자는 묵시적으로 기본 클래스의 기본 생성자 선택

  • 파생 클래스의 매개 변수를 가진 생성자가 기본 클래스의 기본 생성자를 호출

basiccon2

파생 클래스의 생성자에서 명시적으로 기본 클래스의 생성자 선택

basiccon3

컴파일러의 기본 생성자 호출 코드 삽입

con2

6절. 다중 상속

기기의 컨버전스와 C++의 다중 상속

ti

다중 상속 선언 및 멤버 호출

  • 다중 상속 선언
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();
};
  • 다중 상속 활용 1
void MusicPhone::dial(){
 play();          // MP3 클래스의 play() 함수 호출
 sendCall();      // MobilePhone 클래스의 sendCall() 함수 호출
}
  • 다중 상속 활용 2
int main(){
 MusicPhone hanPhone;
 hanPhone.play();               // MP3 클래스의 play() 함수 호출
 hanPhone.sendSMS();            // MobilePhone 클래스의 sendSMS() 함수 호출
}
  • 예제 7. Adder와 Subtractor를 다중 상속받는 Calculator 클래스 작성 예제
    SourceCodeChecking

다중 상속의 문제점

  • 기본 클래스 멤버의 중복 상속
  • 기본 클래스의 멤버가 이중으로 객체에 삽입되는 문제점
  • 동일한 x를 접근하는 프로그램이 서로 다른 x에 접근하는 결과를 발생시킴
    • 즉, 잘못된 실행 오류가 발생

ti2

7절. 가상 상속

가상 상속

  • 다중 상속으로 인한 기본 클래스 멤버의 중복 상속 해결
  • 가상 상속이란?
  • 파생 클래스의 선언문에서 기본 클래스 앞에 virtual로 선언
  • 파생 클래스의 객체가 생성될 때 기본 클래스의 멤버는 오직 한 번만 생성
    • 기본 클래스의 멤버가 중복하여 생성되는 것을 방지
class A : virtual public BaseIO{
// A 클래스는 BaseIO 클래스를 가상 상속
};

가상 상속의 해결법

  • 가상 상속을 통해 다중 상속의 모호성 해결

vi