[CPP] 상속 1

8장. 상속

주제
 - 새로운 클래스를 만드는 방법으로써 상속
    1) 포인터형 멤버가 없는 경우
    2) 포인터형 멤버가 있는 경우
 - 파생 클래스의 객체
 - 업캐스팅과 다운캐스팅
 - public/private/protectd 멤버 접근 제어
 - 상속관계에서 생성자와 소멸자 호출 순서
   (초기화 섹션에서 기반 클래스의 생성자 선택)
 - 상속 방법 : public, : private, : protected
 - 다중 상속
 - 가상 상속 (cf. 다중 상속)



1. 직원을 표현하는 클래스 SalariedEmployee와 HourlyEmployee를 만들기
2. 멤버 name, ssn, netpay가 겹치는 것을 확인
3. 겹치는 부분을 표현하는 Employee 클래스를 만들고 상속
4. 파생 클래스의 생성자와 일반 멤버함수 만드는 요령
     (부모 클래스의 멤버를 모두 물려받으나 
      직접 언급할 수는 없음)
5. void printName(Employee x) { cout << x.getName(); } 
   printName( SalariedEmployee() );
   printName( HourlyEmployee() ); 


6. IsA 관계 (상속) HasA 관계 (멤버 변수로 Employee 객체를 포함) 
  - 유사점 : SalariedEmployee가 4개 멤버 변수를 갖고 
         HourlyEmployee가 5개 멤버 변수를 갖으나
        공통 부분 3개를 Employee 멤버 변수로 대체한 점 
  - 차이점 : 상속 관계가 아니면 printName을 공유할 수 없다.
        (상속 관계에 의한 형 호환성이 없음) 

기존 클래스를 확장 또는 일부 수정하여 새로운 클래스를 만드는 방법 
 - 기반 클래스(Base Class) -- 상속--> 파생 클래스(Derived Class)
 -  부모 클래스 -- 상속--> 자식 클래스


 - 상속 관계에 있는 클래스라면 남남이 아니다!

     => 부모 클래스의 객체를  요구하는 자리에서
          자식 클래스의 객체를 대신 사용할 수 있다!  (효도할 수 있다.)

     => 상속 관계가 아닌 남남 클래스들끼리는 대신 사용할 수 없음
          대신 사용하려고 하면 타입 오류로 컴파일 에러   (부모가 대신해 줄 수 없다.)


Q. Employee 클래스를 상속받아 SalariedEmployee 클래스를 정의해보시오.



두 가지 상황에서 파생 클래스 만들기


 1) 기반 클래스와 파생 클래스에 포인터형 멤버 변수가 없는 경우
   (ex. Employee ----> HourlyEmployee
          Employee ----> SalariedEmployee )

     1) 기반 클래스의 멤버가 private이면
         파생 클래스에서 비록 이 private 멤버를 물려받긴 하지만
         이 멤버 이름을 직접 불러 사용할 수 없다. (기반 클래스의 밖 위치이므로)

         => 파생 클래스에서 기반 클래스를 생성자를 선택할 때
              초기화 섹션 사용하는 방법

     2) 파생 클래스의 생성자를 먼저 호출하되 아직 실행하지 않은 상황에서
         기반 클래스의 생성자를 호출하여 실행을 완료하면
         파생 클래스이 생성자 코드를 실행한다.


     3) protected 키워드
             상속 관계에 있는 클래스들만 직접 사용


 2) 기반 클래스와 파생 클래스에 포인터형 멤버 변수가 있는 경우
   (ex. PFArrayD ----> PFArrayDBak)

   복사 생성자, 할당 연산자, 소멸자를 
     a) 깊은 복사/삭제 방식으로 구현할지
     b) 얕은 복사/삭제 방식으로 구현할지

    깊은 복사/삭제 방식인 경우 부모 클래스의 복사 생성자, 할당 연산자, 소멸자를
    사용하여 자식 클래스의 복사 생성자, 할당 연산자, 소멸자를 구현하는 방법!!!

Q. PFArrayDBak 파생 클래스를 정의한 것을 흉내내어
    TableBak 파생 클래스를 정의하시오.

     - 복사생성자, 할당연산자, 소멸자를 깊은 방식을 선택해 구현하시오.
     - backup과 restore 메소드를 추가하시오.
     - TableBak 클래스를 사용하는 main 함수를 작성하시오.

Q
  - PFArrayD 클래스와 PFArrayDBak 클래스를 사용하는 아래 예제 코드에서
    각 문장이 실행될 때마다 
       1) 호출되는 멤버함수를 나열하고, 
       2) 객체에 포함된 포인터형 멤버를 유념하여 각 문장 실행 직후의 객체의 모양을 그리시오.


다중 상속

  - 둘 이상의 기반 클래스를 상속
  - class A : public B, public C {
    }

  - B와 C가 동일한 클래스라면 A의 객체에 포함될 멤버가 중복될 수 있다. 
    이때 B로 부터 유래한 멤버인지, C로 부터 유래한 멤버인지 구분하려면 
    영역 지정 연산자(::)를 사용한다.



가상 상속 (cf. 다중 상속)

  - class istream : virtual public ios { ... }
    class ostream : virtual public ios { ... }
    class iostream : public istream, public ostream { ... }




Leave a Reply

Your email address will not be published. Required fields are marked *