Game Tech Blog
Theory - Virtual Table 본문
Virtual Table ( vtable ) ?
가상함수 테이블이란, 한 개 이상의 가상 함수 (Virtual Method)를 포함하는 클래스에 대해서 컴파일러가
생성하는 테이블. Key(식별자) , Value(함수의 주소) 로 구성되어 있다.
가상함수 포인터를 모아둔 배열이라고도 한다.
이 가상함수 테이블이 존재하는 클래스에 대해서는 vptr(가상함수 포인터) 가 클래스 내부에 생성된다.
Code
다음과 같은 코드를 짜면 vtable의 어떻게 구성되는지 알아볼 수 있다.
#include "stdafx.h"
#include <iostream>
using namespace std;
class Parent
{
public:
virtual void MyFunc1() { cout << "Parent" << endl; };
void MyFunc2() { cout << "Parent" << endl; };
virtual void MyFunc3() { cout << "Parent" << endl; };
};
class Child : public Parent
{
public:
virtual void MyFunc1() { cout << "Child" << endl; };
void MyFunc2() { cout << "Child" << endl; };
virtual void MyFunc3() { cout << "Child" << endl; };
};
void main(void)
{
Child* Test = new Child;
Parent* Test2 = new Parent;
Parent* Test3 = new Child;
}
이렇게 짜게되면 vtable은 다음과 같이 나올 것이다.
Test, Test3 의 Func1,3 이 virtual 화 된 경우이고, Test2는 실 객체의 vtable을 따라가서 아예 가상함수 포인터가
다른 주소를 지칭하고 있어서 내부 함수의 주소도 다르게 나온다.
Func가 virtual로 Override 되고 있지 않아 서로 다른 주소를 향하고 있다.
각 객체마다 vtable이 생성되는데, 각 vtable의 위치는 배열의 0번 인덱스 지점을 가리키는 것처럼 객체의 시작
지점에 위치한다. 각 포인터 변수가 가리키는 곳은 다음과 같다. -> ( 객체의 시작점 == vtable의 시작점 )
vtable의 생성되는 원리는 "부모로 부터 가상함수 테이블을 복사해와서 본인이 새롭게 선언한 가상함수를 맨
아래에 추가한다" 라고한다.
자식 객체를 UpCasting 해서 부모 메서드를 호출하면?
부모 객체 포인터 + 실 자식 객체 + 가상함수를 호출하면 어떤 함수를 호출하는지 궁금해졌다.
기본 가상함수와 vtable의 이론을 따라가보면 결국 자식의 가상함수를 호출해야하는데 해봐야겠다.
대강 순서는 이럴 것으로 생각한다.
Test Upcast
ㄴTest->MyFunc1() 주소호출 하기위해 vtable 참조
ㄴ vtable에 주소를 타고들어감
ㄴ 그게 Child의 MyFunc1() 호출
가상 키워드나 테이블의 개념을 할때마다 헷갈려서 할때마다 다시 이해해야 한다....
이번에 하면서 새로알게된 점은 void(*fp)(); 함수포인터를 이용해서 가상함수의 주소를 담을 수 없다?
라는 점인데 이것도 확실한지 모르겠다. 문법을 잘못쓴건지.. 나중에 다시 알아봐야할 듯하다.
'Preparing for an Interview > C++ 정리' 카테고리의 다른 글
스마트 포인터란? (개념, 질문답변) (0) | 2020.11.13 |
---|---|
객체 지향 프로그래밍이 무엇인가요? (키워드, 개념) (0) | 2020.11.13 |