Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 가상 함수(Virtual Function) 구현 방법과 동작 원리

C++의 가상 함수(virtual function)는 기본 클래스 포인터들의 목록을 만들어 두고, 파생 클래스 객체의 실제 타입을 알지 못하더라도 해당 파생 클래스의 메서드를 호출할 수 있도록 해주는 핵심 기능입니다. 가상 함수는 컴파일 시점이 아닌 런타임에 호출 대상이 결정되며, 이러한 방식을 늦은 바인딩(late binding) 또는 동적 바인딩이라고 부릅니다.

내부적으로는 virtual 키워드가 붙은 함수마다 클래스 단위의 가상 함수 테이블(vtable)이 생성되고, 각 객체는 자신의 vtable을 가리키는 숨겨진 포인터를 가집니다. 함수 호출 시 런타임에 이 테이블을 조회하여 실제 실행할 함수 버전을 찾아내는 원리입니다.

예제 코드

#include <iostream>
using namespace std;

class B {
    public:
        virtual void s() { // 가상 함수 선언
            cout << "In Base \n";
        }
};

class D : public B {
    public:
        void s() { // 함수 재정의(오버라이딩)
            cout << "In Derived \n";
        }
};

int main(void) {
    D d;        // D 클래스 객체 생성
    B *b = &d;  // B* 타입 포인터가 d를 가리킴
    b->s();     // 런타임에 D::s()가 호출됨
    return 0;
}

실행 결과

In Derived

코드 설명

클래스 B의 멤버 함수 s() 앞에 virtual 키워드가 붙어 있어 가상 함수로 선언되었습니다. 파생 클래스 D는 이 함수를 재정의(override)합니다.

main 함수에서는 B 타입의 포인터 b가 D 객체 d의 주소를 가리킵니다. 여기서 b->s()를 호출하면, 포인터의 정적 타입(B)이 아니라 실제 객체의 타입(D)을 기준으로 함수가 선택됩니다. 그 결과 "In Derived"가 출력됩니다.

만약 virtual 키워드가 없었다면 정적 바인딩에 의해 포인터 타입을 따라가 "In Base"가 출력되었을 것입니다. 이처럼 가상 함수는 C++에서 다형성(polymorphism)을 구현하는 핵심 메커니즘이며, 기본 클래스 포인터 하나만으로 다양한 파생 클래스 객체의 동작을 유연하게 처리할 수 있게 해줍니다.