학습일지/C와 C++

C/C++ 상속과 다형성, 추상 클래스

Tsukino Ren 2026. 3. 12. 12:58

상속 (Inheritance)

  • 공통 기능을 부모에 모아두고, 자식이 그걸 기반으로 확장하는 방식이다
  • 자식 클래스는 부모 클래스의 멤버 변수와 멤버 함수를 그대로 사용할 수 있다
  • 본인 클래스만의 멤버 변수와 멤버 함수도 추가 할수 있다

상속은 왜 필요한가?

  • 코드 재사용성
똑같은 멤버 변수와 똑같은 멤버 함수들을 가진 두 클래스가 있다면 
해당 멤버 변수와 멤버 함수를 부모 클래스로 묶어 버리기 위함.
  • 확장성
공통 부분은 부모 클래스에 두고, 자식클래스 만의 멤버 함수와 멤버 변수들을 가지고
자식 클래스의 기능을 좀 더 확장 할 수 있다.
  • 유지보수에 유리
공통 부분을 부모 클래스에 묶어두면, 부모 클래스 한 곳만 수정하면
많은 자식 클래스의 부분에도 자동으로 적용된다.

잘못 바꾸면 영향을 미치는 곳이 많다는 것이 단점이나 신경써서 제대로만 사용한다면 장점이다.

자식 클래스를 정의

Class 자식클래스명 : public 부모클래스명
{
};

Class Songoku : public Human
{
};
  • 먼저 자식클래스명을 적어주고 public <상속 접근 제한자> 을 통해 부모 클래스에서 어떤 권한으로 가져올지 결정한다.
  • public 상속부모의 public 멤버를 자식에서도 public 으로 유지한다
  • : (콜론)상속 관계임을 나타내는 구분자이다.

멤버 함수와 멤버 변수

  • 객체 지향 프로그래밍(Object-Oriented Programming, OOP)에서의 멤버 함수는 해당 객체의 "행동", "동작"을 의미한다
    예시 ) void Walk();, void Attack(); 같이 행동을 사용할 때
예시 ) 
void Walk()
{
 // ~~은 걷는다
}
void Attack()
{
// ~~은 ~~으로 공격한다
}
  • 멤버 변수는 해당 객체의 "속성" 을 의미한다.
예시 ) 
std::string Name;
int HP;
int SP;
int ATK;

상속 관계에서 생성자/소멸자

  • 상속 관계에 있다면, 자식 클래스의 객체가 만들어지거나 지워질 때 부모 클래스의 생성자와 소멸자도 같이 호출된다.
  • 생성자는 부모 클래스의 생성자가 먼저 호출 -> 자식 클래스의 생성자 호출된다.
  • 반대로 소멸자는 자식 클래스의 소멸자 -> 부모 클래스의 소멸자 호출된다.
// 명시적 호출
Songoku::Songoku(std::string Name)
      : Human(Name)
{
}

// 암시적 호출
Songoku::Songoku(std::string Name)
{
}
delete Goku;
// ~Songoku()가 실행된 뒤 ~Human()이 실행된다.

다형성

다형성(Polymorphism)은 "여러 개의 형태를 가진다"라는 뜻으로 함수 이름은 같지만
실제 작동하는 방식은 타입에 따라 달라지는 것을 말한다.

가상 함수 (Virtual Function)

  • 부모 클래스에서 함수를 virtual 로 선언하면, 자식 클래스에서 재정의(override)한 함수가 호출되도록 보장한다.

※ 가상 소멸자

delete Goku;를 할 때, 컴파일러는 포인터 타입인 SonGoku의 소멸자만 호출하고 끝낸다.

자식 클래스에서 할당한 추가 메모리나 자원이 해제되지 않아 
메모리 누수(Memory Leak)가 발생한다.

부모 소멸자에 virtual을 붙이면, 런타임에 실제 객체가 무엇인지 확인하여 
자식 소멸자부터 부모 소멸자까지 순서대로 안전하게 호출한다.

순수 가상 함수

순수 가상 함수(Pure Virtual Function)는 자식 클래스에서 반드시 
재정의(Override)해야만 하는 함수다. 

손오공 비유를 이어가자면, 
"손오공은 무엇이든 변신할 수 있지만, '그냥 변신'이라는 추상적인 상태는 존재하지 않는다"는 
규칙을 만드는 것과 같다.

특징

  • 함수 선언 뒤에 = 0; 을 붙여서 만든다.
  • 추상 클래스는 순수 가상 함수를 하나라도 가진 클래스로 객체를 직접 생성 할 수 없다.
예시)
new Human()이 안된다
  • 상속받은 자식 클래스는 반드시 순수 가상 함수를 정의해야 하며, 정의 하지않으면 객체를 생성할 수 없다.

인터페이스(Interface)

C++ 에서는 인터페이스 라는 클래스를 문법적으로 지원하지 않는다.
추상 클래스를 통해 마치 인터페이스 처럼 사용할 수 있다.

예시)

  • 손오공은 에네르기파를 쓸 수 있다.
  • 손오반도 에네르기파를 쏠 수 있다.
  • 피콜로는 마관광살포를 쏠 수 있다.
  • 베지터는 기공포를 쏠 수 있다.

기술은 다르지만, 공통적으로 전투 가능 이라는 성질을 가진다. 이럴 때 사용하는 것이 바로 인터페이스다.

// IFighter.h

#include <iostream>
#include <string>

class IFighter
{
public:
    virtual void Attack() = 0;        // 기본 공격. 반드시 오버라이딩 해야하는 함수
    virtual void SpecialMove() = 0;   // 필살기. 역시 오버라이딩 해야하는 함수
    virtual ~IFighter() {}            // 가상 소멸자. 부모 포인터로 자식 객체를 안전하게 삭제하기 위해 넣는다.
};

 

class Goku : public IFighter
{
public:
    void Attack() override
    {
        cout << "날라 차기!" << endl;
    }

    void SpecialMove() override
    {
        cout << "에네르기파!!!" << endl;
    }
};

왜 인터페이스를 쓰는가 ?

각 캐릭터가 전부 다른 클래스 임에도 부모 타입인 IFighter로 묶어서 다룰 수 있다는 점이 있다.
즉 프로그램 입장에서는

  • 손오공
  • 베지터
  • 피콜로

굳이 세세하게 구분하지 않아고 하나의 전투 가능한 객체 라는 공통 개념으로 처리 할 수 있다.


핵심 정리

  • 상속은 공통 기능을 부모에 모아 재상용성을 높인다
  • virtual 함수는 실제 객체의 함수를 호출하게 한다
  • 순수 가상 함수는 자식 클래스에서 반드시 구현해야 한다
  • 인터페이스는 공통 행동을 묶어 객체를 같은 타입으로 다룰 수 있게 한다

마무리

정리하다보니 결국 심화과정에 있는 내용도 필요하다는 걸 느꼇다.

열심히 공부해서 C++에 친숙해지고 익숙해지면 심화과정도 정리 해보고싶다..

'학습일지 > C와 C++' 카테고리의 다른 글

C++ Template Programming  (0) 2026.03.13
C++ std::string  (0) 2026.03.13
C++ RPG 전투 시스템 구현 과제  (0) 2026.03.11
C++ 복사 생성자와 오버로딩  (0) 2026.03.11
C/C++ 전직  (0) 2026.03.10