Language/C++

[C++] 18.Unmanaged Programming: 상속(Inheritance)

coco_daddy 2024. 1. 30. 13:13

상속 예제

// Animal.hpp
class Animal
{
public:
    Animal(int age);
    ~Animal(); // 소멸자 추가
private:
    int mAge;
};
// Cat.hpp
class Cat : public Animal
{
public:
    Cat(int age, const char* name);
    ~Cat(); // 소멸자 추가
private:
    char* mName;
};
// Cat.cpp
Cat::Cat(int age, const char* name)
    : Animal(age)
{
    size_t size = strlen(name) + 1;
    mName = new char[size];
    strcpy(mName, name);
}

Cat::~Cat()
{
    delete[] mName;
    // Animal의 소멸자가 자동으로 호출됨
}
  1. 초기화 리스트에서 부모의 생성자를 먼저 호출해준다.
  2. Cat에서 받아야하는 인자들만 처리를 해준다.
    • 파생 클래스의 생성자에서는 파생 클래스에서 추가된 멤버 변수들을 초기화 해준다.
    • 부모 클래스로 넘겨준 인자들이 적절히 처리될 것이라는 가정 하에 작성한다.

상속이란?

  • 다른 클래스의 특성을 내려 받는다.
    • 부모 클래스 (base class, 베이스 클래스)
    • 자식 클래스 (derived class, 파생 클래스)
  • 파생 클래스 개체가 부여받는 것들:
    • 베이스 클래스의 멤버 변수
    • 베이스 클래스의 멤버 메서드
    • 자신의 생성자와 소멸자
  • 파생 클래스는 멤버 변수 및 메서드를 추가할 수 있다.

파생 클래스를 정의하는 법

class <파생 클래스 이름> : <접근 제어자> <베이스 클래스 이름> {};
  • class Cat : public Animal {};
  • class Honda : private Car {};
  • class AndroidPhone : protected Phone {};

파생 클래스의 접근 제어자

상속받은 개체의 메모리의 형태

Animal* a = new Cat(..., ...);
  1. main.cpp에서 new Cat(..., ...)을 호출.
  2. Cat.cpp의 생성자로 이동.
  3. 초기화 리스트의 부모 생성자로 이동.
    • 총 할당된 크기는 Animal의 int age + Cat의 char* mName

  • 부모 자식 간에 메모리가 연결되어 있습니다. Cat이 잡고 있는 메모리는 부모의 메모리부터 잡힌다.
    > 부모 오브젝트가 초기화되어야 자식의 오브젝트가 초기화될 수 있는 이유.

생성자 호출 순서

  • 베이스 클래스의 생성자가 먼저 호출되어야 한다.
    • 명시적으로 하지 않는다면 암시적으로 호출이 된다.
  • 부모 클래스의 특정 생성자를 호출할 때에는 초기화 리스트를 사용해야 한다.
Cat::Cat(int legs, int age, const string& callingName)
    : Animal(legs, age) // 명시적 호출
    , mCallingName(callingName)
{
}
  • 암시적으로 부모 클래스에서 생성자 호출하기
    • 매개변수 없는 생성자(default 생성자)가 있는 부모 클래스
    • 매개변수 없는 생성가자 없는 부모 생성자
      > 컴파일 에러

 

자식 개체 지우기

// Animal.cpp
Animal::~Animal() {}

// Cat.cpp
Cat::~Cat()
{
    delete[] mName;
    // Animal의 소멸자가 자동으로 호출됨
}

// main.cpp
delete myNeighborsCat;
  1. main.cpp에서 Cat 오브젝트를 delete로 지우려고 한다.
  2. Cat의 소멸자부터 호출이 된다.
  3. Cat의 소멸자가 끝나면서 Animal의 소멸자를 호출.

왜 자동으로 호출이 되는가?

  • 소멸자는 하나밖에 없으므로 지정해주지 않아도 마지막에 호출이 된다.