프로그래밍 언어/C++

C++에서 배우는 가상 함수

로안님 2025. 1. 21. 20:22

게임 개발에서는 다양한 캐릭터, 동작, 오브젝트를 다루어야 하므로, 다형성(polymorphism)의 개념이 필수적입니다. 오늘은 C++의 가상 함수를 활용해 캐릭터 행동을 구현하는 방법을 정리해 보겠습니다.


1. 가상 함수란?

가상 함수는 부모 클래스에서 선언하고, 자식 클래스에서 고유하게 재정의(override)할 수 있는 함수입니다.
이 기능을 통해 C++은 다형성(polymorphism)을 지원하며, 부모 클래스의 포인터나 참조를 통해서도 자식 클래스의 고유 동작을 실행할 수 있습니다.


2. 왜 가상 함수가 필요한가?

  • 공통된 동작고유한 동작을 함께 처리하기 위해 사용됩니다.
  • 게임 개발에서 다양한 캐릭터(예: 강아지, 고양이)가 있을 때, 공통적으로 걷는 동작(Walk)은 부모 클래스에서 제공하고, 고유한 소리(SoundPlay)는 자식 클래스에서 각각 정의할 수 있습니다.

하지만, 걷는 동작조차 캐릭터마다 다르다면 어떨까요?
예를 들어, 강아지는 터벅터벅 걷고, 고양이는 살금살금 걷습니다. 이 경우 걷는 동작도 가상 함수로 선언하고, 자식 클래스에서 각각 다르게 구현해야 합니다.


3. 가상 함수 구현 예시

기본적인 가상 함수와 다형성 구현

class IAnimal
{
protected:
    string name;

public:
    IAnimal(string _name) : name(_name) {}

    // 걷는 동작 - 각 캐릭터마다 다르므로 가상 함수로 선언
    virtual void Walk() = 0;

    // 고유한 소리
    virtual void SoundPlay() = 0;

    virtual ~IAnimal() {} // 안전한 소멸자
};

class Dog : public IAnimal
{
public:
    Dog(string _name) : IAnimal(_name) {}

    void Walk() override
    {
        cout << name << "가 터벅터벅 걷습니다." << endl;
    }

    void SoundPlay() override
    {
        cout << name << " : 멍멍!" << endl;
    }
};

class Cat : public IAnimal
{
public:
    Cat(string _name) : IAnimal(_name) {}

    void Walk() override
    {
        cout << name << "가 살금살금 걷습니다." << endl;
    }

    void SoundPlay() override
    {
        cout << name << " : 야옹!" << endl;
    }
};

4. 가상 함수의 동작 방식

부모 클래스 포인터로 호출하기

가상 함수는 부모 클래스의 포인터를 통해 호출해도 자식 클래스의 재정의된 함수가 호출됩니다.
예를 들어:

int main()
{
    IAnimal* dog = new Dog("강아지");
    IAnimal* cat = new Cat("고양이");

    dog->Walk();        // 강아지가 터벅터벅 걷습니다.
    dog->SoundPlay();   // 강아지 : 멍멍!

    cat->Walk();        // 고양이가 살금살금 걷습니다.
    cat->SoundPlay();   // 고양이 : 야옹!

    delete dog;
    delete cat;

    return 0;
}

결과:

 
강아지가 터벅터벅 걷습니다.
강아지 : 멍멍!
고양이가 살금살금 걷습니다.
고양이 : 야옹!

5. 정리

가상 함수는 다음과 같은 특징이 있습니다:

  1. 부모 클래스에서 선언한 함수는 자식 클래스에서 고유하게 재정의할 수 있습니다.
  2. 부모 클래스의 포인터나 참조를 통해 자식 클래스의 동작을 호출할 수 있습니다.
  3. 게임 개발에서 캐릭터, 무기, 효과음 등 다양한 요소를 구현할 때 필수적으로 사용됩니다.

오늘 배운 것

  1. 공통된 행동은 부모 클래스에서 일반 함수로 구현한다.
  2. 캐릭터마다 동작이 다르면, 가상 함수를 선언하고 자식 클래스에서 구현한다.
  3. 가상 함수와 다형성을 통해 코드의 재사용성과 확장성을 크게 높일 수 있다.