본문으로 바로가기

Inheritance의 이해 - ② 가상 함수 테이블(Virtual table)

virtual 키워드를 사용해서 멤버함수를 재정의할 경우 메모리에서 어떤 일이 일어나는지 가상 함수 테이블을 중심으로 살펴본다. 우선 아래와 같이 virtual을 사용하지 않은 경우를 살펴보자.

class Animal {
public:
    //virtual ~Animal() = default;
    void Speak() 
    {
        std::cout << "Animal" << std::endl;
    }
private:
    double weight;
};
class Cat : public Animal {
public:
    void Speak()
    {
        std::cout << "mew~" << std::endl;
    }
private:
    double height;
};

int main()
{
    Animal *animal = new Animal();
    Animal *cat = new Cat();

    animal->Speak();
    cat->Speak();
    std::cout << "Animal:" << sizeof(Animal) <<" Cat: " << sizeof(Cat) << std::endl;
    return 0;
}
Animal
Animal
Animal:8 Cat: 16

출력 결과에서 두 가지 특징을 살펴볼 수 있다.

  • Animal* 타입의 cat은 실제 Cat 클래스의 인스턴스지만 Animal 클래스의 Speak() 함수를 사용한다.
  • Animal의 인스턴스의 크기는 8byte(weight) 이고, Cat 인스턴스 크기는 16byte(weight, height)이다.

animalcat 인스턴트의 구조를 살펴보면 다음과 같을 것이다.

가상함수 테이블 생성

이번에는 Animal의 Speak 함수와 소멸자를 다음과 같이 가상 함수(virtual)로 선언해보자.

class Animal {
public:
    virtual ~Animal() = default;
    virtual void Speak() 
    {
        std::cout << "Animal" << std::endl;
    }
private:
    double weight;
};
class Cat : public Animal {
public:
    void Speak() override
    {
        std::cout << "mew~" << std::endl;
    }
private:
    double height;
};

int main()
{
    Animal *animal = new Animal();
    Animal *cat = new Cat();

    animal->Speak();
    cat->Speak();
    std::cout << "Animal:" << sizeof(Animal) <<" Cat: " << sizeof(Cat) << std::endl;
    return 0;
}
Animal
mew~
Animal:16 Cat: 24

여기서 두가지 특징을 살펴보자.

  • Animal* 타입의 cat이 실형식 Cat의 Speak() 함수를 호출했다.
  • Animal과 Cat의 객체크기가 8byte씩 증가하였다.

첫 번째 특징에서 우리는 다형성(Polymorphism)을 확인할 수 있다. 그리고 우리가 별다른 멤버 변수를 선언하지도 않았는데 객체의 크기가 8byte만큼 증가한 것을 확인할 수 있다. 이 8byte는 가상 함수 테이블의 주소 값이다.


virtual 키워드를 사용하여서 가상 함수를 만들게 되면 컴파일러는 가상함수 테이블(Virtual Function Table / vftable)을 만들고 객체에는 어느 가상함수 테이블을 참조할지 정하는 가상함수 포인터(Virtual Function Pointer / vfptr)를 만든다. 그리고 생성되는 인스턴스의 실형식에 따라서 어느 가상 함수 테이블을 참조할지를 결정하여 Dynamic Polymorphism을 구현할 수 있게 된다.

 


출처: https://www.youtube.com/channel/UCHcG02L6TSS-StkSbqVy6Fg