C++ 가상 함수(1)

sjongyuuu·2021년 6월 5일
0

C++

목록 보기
3/6
post-thumbnail

가상 함수(Virtual Function)

C++에서 클래스의 상속 개념을 공부하면 가상 함수라는 개념이 등장한다. 이 개념을 공부할 당시 어떻게 동작하는지에 대해선 파악했지만 이것의 목적이 무엇인지 또 오버라이딩(Overriding)과는 무슨 차이인지 이해가 잘 되지 않았다. 그래서 C++ 가상 함수 포스팅을 통해 다시 한 번 천천히 개념을 정리하면서 이해해 보려 한다.

먼저, 이번 포스팅에서는 가상 함수가 등장하기 이전 상황에 대해 이야기 해보려 한다.

다음 코드를 보자.

#include <iostream>
using namespace std;

class Mom {
public:
    void nag() {...}
    void shout() {
    	cout << "Do your homework!" << endl;
    }
};

class Son:: public Mom {
public:
    void play() {...}
    void shout() {
    	cout << "I want to play a game" << endl;
    }
};

Mom 클래스(수퍼 클래스)를 상속 받는 Son 클래스(서브 클래스)가 구현되어 있고 Son 클래스의 shout() 함수는 오버라이딩 된 것을 알 수 있다.

이때, main() 함수를 한 번 보자.

int main() {
    Mom *m;
    Son s;
    m = &s;
    
    m.nag();  // OK!
    m.play(); // compile error
    m.shout(); // ??
        
    return 0;
}

Son 클래스 타입의 객체 s가 생성되어 있고 Mom 클래스 타입의 포인터 변수 m이 선언되어 있다.
다음으로, s의 reference(주소값)를 m에 저장하는 것으로 서브 클래스 타입의 변수가 수퍼 클래스 타입의 변수에 저장되고 있다.

즉, Upcasting(상향 형변환)이 일어나고 있다.

Upcasting을 통해 정의된 변수 m은 자신의 클래스(Mom)에 속하는 멤버엔 접근이 가능하지만 서브 클래스(Son)에 속하는 멤버엔 접근이 불가능하다.
이를 통해, m.shout()도 Mom 클래스의 멤버 함수 shout()가 실행된다는 것을 알 수 있다.

그렇다면...

Upcasting을 통해 정의된 슈퍼 클래스(Mom)의 객체로 서브 클래스(Son)의 오버라이딩된 함수(shout)를 실행할 수 있는 방법은 없을까?

이 질문에 대한 답이 가상 함수라고 할 수 있다.

다음 코드를 보자.

#include <iostream>
using namespace std;

class Mom {
public:
    void nag() {...}
    virtual void shout() {
    	cout << "Do your homework!" << endl;
    }
};

class Son:: public Mom {
public:
    void play() {...}
    void shout() {
    	cout << "I want to play a game" << endl;
    }
};

첫 번째 코드에서 Mom 클래스의 shout() 함수에 "virtual"이라는 키워드를 붙여줬다. 이 키워드를 통해 Mom 클래스의 shout() 함수는 가상 함수로서 동작하게 된다.

다시 이전에 작성했던 main() 함수를 보자.

int main() {
    Mom *m;
    Son s;
    m = &s;
    
    m.nag();  // OK!
    m.play(); // compile error
    m.shout(); // ??
        
    return 0;
}

nag() 함수와 play() 함수는 위와 동일한 결과를 보이지만 shout() 함수는 Son 클래스의 shout() 함수가 실행된다.
이것이 가능한 데에는 Mom 클래스에서 shout() 함수를 가상 함수로 선언한 것과 관련이 있다는 것을 알 수 있을 것이다.

그렇다면... 가상 함수로 선언함으로써 어떻게 동작하게 되는 것일까?

이를 이해하기 위해서 먼저, 바인딩(Binding)에 대한 이해가 필요하다.

.
.
.

다음 포스팅 "C++ 가상 함수(2)"에서 계속됩니다.

  • 읽어 주셔서 정말 감사드립니다.
  • 오타나 잘못된 정보를 댓글로 남겨주시면 정말 감사하겠습니다.
profile
개발 잘 하고 싶다

0개의 댓글