Minwoo Dev.

[C++] 가상 함수(Virtual Function) 본문

C++

[C++] 가상 함수(Virtual Function)

itisminu 2024. 7. 17. 23:37
728x90
반응형
SMALL

C++에서 상속과 다형성의 개념을 사용하다 보면, 오버라이딩 된 함수 중 원하는 것을 호출하기 힘든 상황이 있다.

 

 

예를 들어, 아래와 같이 Animal, MomDog, BabyDog라는 클래스가 존재하고 Animal <- MomDog <- BabyDog순서로 상속 관계에 있다고 하자.

#include<iostream>
using namespace std;


class Animal{
private:
    int age;
    int height;
public:
    Animal(int a, int h) : age(a), height(h){}
    void Introduce(){
        cout << "I am just Animal." << endl;
    }
    int GetAge() const{
        return age;
    }
    int GetHeight() const{
        return height;
    }
};

class MomDog : public Animal
{
public:
    MomDog(int a, int h):Animal(a,h){}
    void Introduce(){
        cout << "I am Mommy Dog! my height is " << GetHeight() << ", and my age is " << GetAge() << endl;
    }
};

class BabyDog : public Animal
{
public:
    BabyDog(int a, int h):Animal(a,h){}
    void Introduce(){
        cout << "I am Baby Dog! my height is " << GetHeight() << ", and my age is " << GetAge() << endl;
    }
};



int main(void){
    Animal *ani = new BabyDog(3,50);
    ani->Introduce();
}

 

 

실행 결과

 

main함수에서 다형성 중 업캐스팅을 사용하여 Animal 클래스의 참조로 BabyDog 객체를 가리키고 있다.

이 상황에서 우리는 Introduce 함수를 실행하면 어떤 클래스의 introduce 함수가 실행되겠는가 ?

  1. 타입으로 작성한 Animal 클래스의 Introduce함수가 실행될 것이다.
  2. 실제로 안에 들어가있는 객체값의 함수인 BabyDog의 Introduce 함수가 실행될 것이다.

 

정답은 1번이다. 아무런 키워드 없이 저러한 형태로 선언되어 있다면, 객체를 가리키고 있는 범위 안에서 선택하게 된다.

 

하지만,  우리는 실제로 담겨있는 객체의 Introduce 함수에 접근하고 싶다.

그럴 때 사용하는 것이 바로 가상 함수(Virtual Function)이다.

 

가상 함수(Virtual Function)

상속 관계에 있고, 다형성을 통해 접근하고 있는 상태에서 실제 담겨있는 멤버 변수에 접근하려고 할 때 사용한다.

  • 제일 상위 멤버변수에만 virtual을 붙여줘도 상속받은 모든 클래스에서는 해당 함수가 가상 함수로 인식된다.

 

#include<iostream>
using namespace std;


class Animal{
private:
    int age;
    int height;
public:
    Animal(int a, int h) : age(a), height(h){}
    virtual void Introduce(){ // virtual 추가
        cout << "I am just Animal." << endl;
    }
    int GetAge() const{
        return age;
    }
    int GetHeight() const{
        return height;
    }
};

class MomDog : public Animal
{
public:
    MomDog(int a, int h):Animal(a,h){}
    void Introduce(){ // virtual 키워드 작성해도 됨
        cout << "I am Mommy Dog! my height is " << GetHeight() << ", and my age is " << GetAge() << endl;
    }
};

class BabyDog : public Animal
{
public:
    BabyDog(int a, int h):Animal(a,h){}
    void Introduce(){ // virtual 키워드 작성해도 됨
        cout << "I am Baby Dog! my height is " << GetHeight() << ", and my age is " << GetAge() << endl;
    }
};



int main(void){
    Animal *ani = new BabyDog(3,50);
    ani->Introduce();
}

 

위처럼 가상 함수로 만들 함수에 virtual 키워드를 붙이고 실행해보면,

 

BabyDog의 Introduce가 실행된 것을 확인할 수 있다.

 

 

 

이처럼 가상 함수는 업캐스팅과 같은 다형성을 사용할 때, 내부에 실제로 담고 있는 객체에 대해 접근을 시도하기 때문에 중요한 개념이다. 

728x90
반응형
LIST