[C++] 추상 클래스(abstract class)

2022. 7. 7. 17:46Languages/C++

 

 

 

추상 클래스의 필요성

class Monster {
public:
    Monster() {}
    virtual ~Monster() {}
    virtual void Attack()
};

 

  • 슬라임, 리본돼지 등의 몬스터 클래스를 만들 예정인데, 이들은 모두 공격(Attack)이라는 메소드를 가진다.
  • 이들은 저마다 다른 공격을 구사한다.
  • 따라서, 슬라임과 리본돼지의 부모 클래스로 Monster 클래스를 만들어서 Attack() 메소드를 만들어 주었다.
  • 하지만 이 Monster 클래스는 공통된 멤버를 정의하기 위한 용도일 뿐이지, 실제 객체 생성은 요구되지 않는다.
  • 가상 함수로도 공격 메소드의 다형성을 구현할 수 있지만, 프로그래머가 오버라이드 하는 걸 까먹을 수도 있다.
  • 다음과 같은 내용들을 만족하는 방법이 있었으면 좋겠다.
    • 객체 생성은 불가능하나, 자기 자신을 상속받는 자식 클래스를 가리킬 수 있다.
    • 오버라이드를 강제하게 하여, 프로그래머가 까먹지 않고 구현할 수 있도록 한다.

 

 

위에 딱 어울리는 것이 바로 추상 클래스!

class Monster {
public:
    Monster() {}
    virtual ~Monster() {}
    virtual void Attack() = 0;  // 순수 가상 함수(pure virtual function)
};

 

  • 가상 함수에 = 0; 을 붙여, 순수 가상 함수(pure virtual function)을 만들 수 있다.
    • 반드시 오버라이딩이 되도록 강제하는 함수를 뜻한다.
    • 순수 가상 함수는 본체가 없기 때문에 직접 이 함수를 호출하는 것은 불가능
    • 그렇기 때문에 해당 클래스의 객체 생성 또한 불가능
    • C++ 개발자들은 순수 가상 함수 호출 금지 대신, 해당 함수가 포함되는 클래스의 객체 생성을 막았음
  • 순수 가상 함수를 최소 한 개 이상 포함하는 클래스를 인스턴스화 시키기 위해서는 이 클래스를 상속 받는 클래스를 만들어서, 모든 순수 가상 함수를 오버라이딩 해야 한다.
    • 이렇게 순수 가상 함수를 최소 한 개 포함하고 있어, 반드시 상속 되어야 하는 클래스추상 클래스(abstract class)라고 한다.
    • private 영역 안에 순수 가상 함수를 정의하여도 문제가 되지 않는다. 오버라이드를 못하는 것이 아니기 때문
    • 다만, 자식 클래스에서 호출할 수 없다.

 

 

추상 클래스를 상속 받아 구현한 Slime, RibbonPig 클래스들

class Slime : public Monster {
public:
    Slime() : Monster() {}
    void Attack() override { std::cout << "슬라임의 공격" << std::endl; }
};

class RibbonPig : public Monster {
public:
    RibbonPig() : Monster() {}
    void Attack() override { std::cout << "리본돼지의 공격" << std::endl; }
};

 

추상 클래스는 업 캐스팅이 가능하다.

Monster* monsters[] = { new Slime(), new RibbonPig() };	
monsters[0]->Attack();
monsters[1]->Attack();

 

 

순수 가상 함수를 오버라이딩하였기 때문에, 비록 부모 클래스 포인터이지만 자식 클래스의 메소드가 호출된다. 또 다른 의미로 해석하자면, 순수 가상 함수 자체는 호출할 수 없고 반드시 구현해놨을 것이라는 약속이기에 다형성이 보장되는 것으로 볼 수 있다.

 

 

 

 

 

728x90
반응형