[C++] 상속

·2023년 8월 22일
0

C++

목록 보기
11/17
post-custom-banner

상속

#include <iostream>
#include <string>

class Base 
{
  std::string s;

 public:
  Base() : s("기반") {  std::cout << "기반 클래스" <<  std::endl; }

  void what() {  std::cout << s <<  std::endl; }
};

class Derived : public Base 
{
  std::string s;

 public:
  Derived() : Base(), s("파생") 
  {
     std::cout << "파생 클래스" <<  std::endl;

    // Base 에서 what() 을 물려 받았으므로 Derived 에서 호출 가능
    what();
  }
};

int main() 
{
   std::cout << " === 기반 클래스 생성 ===" <<  std::endl;
  Base p;

   std::cout << " === 파생 클래스 생성 ===" <<  std::endl;
  Derived c;

  return 0;
}

실행 결과
=== 기반 클래스 생성 ===
기반 클래스
=== 파생 클래스 생성 ===
기반 클래스
파생 클래스
기반

생성 시 부모가 있는 경우 부모의 생성자가 호출된 뒤 자식 생성자가 호출됨
부모 클래스의 모든 정보를 상속 받았기 때문에 Derived에서도 what 호출 가능

Derived에도 what이 있다면?

#include <iostream>
#include <string>

class Base 
{
  std::string s;

 public:
  Base() : s("기반") {  std::cout << "기반 클래스" <<  std::endl; }

  void what() {  std::cout << s <<  std::endl; }
};

class Derived : public Base 
{
  std::string s;

 public:
  Derived() : Base(), s("파생") 
  {
     std::cout << "파생 클래스" <<  std::endl;

    what();
  }

  void what() {  std::cout << s <<  std::endl; }
};

int main() 
{
   std::cout << " === 기반 클래스 생성 ===" <<  std::endl;
  Base p;

   std::cout << " === 파생 클래스 생성 ===" <<  std::endl;
  Derived c;

  return 0;
}

실행 결과
기반 클래스
=== 파생 클래스 생성 ===
기반 클래스
파생 클래스
파생

Derived의 what이 호출 됨

두 함수는 같은 이름, 같은 인자를 가지지만 다른 클래스에 정의되어 있기 때문에
다른 함수로 취급됨 (따라서 컴파일 오류 없음)

Derived에 what 함수가 정의되어 있기 때문에 Base의 함수들까지 뒤지지 않고,
바로 앞에 있는 Derived의 what 함수를 호출하게 됨
-> 오버라이딩(overriding)


Protected

class Base 
{
  std::string parent_string;

 public:
  Base() : parent_string("기반") {  std::cout << "기반 클래스" <<  std::endl; }

  void what() {  std::cout << parent_string <<  std::endl; }
};

class Derived : public Base 
{
  std::string child_string;

 public:
  Derived() : child_string("파생"), Base() 
  {
     std::cout << "파생 클래스" <<  std::endl;

    // 그렇다면 현재 private 인 Base의 parent_string 에 접근할 수 있을까?
    parent_string = "바꾸기";
  }

  void what() {  std::cout << child_string <<  std::endl; }
};

컴파일 에러 발생

parent_string는 Base의 private 멤버 변수로 자식도 접근 불가
상속 받는 클래스에서만 접근 가능하게 하기 위해서는 protected 접근 지정자 사용 필요

class Base {
 protected:
  std::string parent_string;

 public:
  Base() : parent_string("기반") {  std::cout << "기반 클래스" <<  std::endl; }

  void what() {  std::cout << parent_string <<  std::endl; }
};
class Derived : public Base {
  std::string child_string;

 public:
  Derived() : Base(), child_string("파생") {
     std::cout << "파생 클래스" <<  std::endl;

    // Base의 parent_string은 protected 이므로 접근 가능
    parent_string = "바꾸기";
  }

  void what() {  std::cout << child_string <<  std::endl; }
};

상속 키워드의 의미

class Derived : public Base

에서 public 부분은 상속 받는 클래스에서 부모 클래스의 멤버들이 실제로 어떻게 작동하는지 영향을 줌

  • public : 부모 클래스의 접근 지시자들에 아무런 영향을 끼치지 않음 (그대로 작동)
  • protected : 부모 클래스의 public은 protected로 바뀌고 나머지는 그대로 작동
  • private : 부모 클래스의 모든 접근 지시자들이 private으로 바뀐 형태로 작동
#include <iostream>
#include <string>

class Base 
{
 public:
  std::string parent_string;

  Base() : parent_string("기반") { std::cout << "기반 클래스" << std::endl; }

  void what() { std::cout << parent_string << std::endl; }
};

class Derived : private Base 
{
  std::string child_string;

 public:
  Derived() : child_string("파생"), Base() 
  {
    std::cout << "파생 클래스" << std::endl;
  }

  void what() { std::cout << child_string << std::endl; }
};

int main() 
{
  Base p;
  // Base의 parent_string 이 public 이므로 외부에서 접근 가능
  std::cout << p.parent_string << std::endl;

  Derived c;
  // 반면에 Derived 에서는 parent_string 을 private으로 상속 받았기 때문에
  // 외부에서 접근 불가능
  std::cout << c.parent_string << std::endl; // 컴파일 오류

  return 0;
}
post-custom-banner

0개의 댓글