C , C++, C#

[C++] 가상함수 테이블

vhxpffltm 2019. 3. 12. 22:24

**면접에서 가상함수가 무엇인지 가상함수 테이블의 생성 등에 대해 묻는 경우가 있다.**


가상함수의 특징은 동적 바인딩으로 컴파일이 아니고 프로그램이 실행, 함수가 호출될 때, 바인딩할 주소가 결정되는것 

그렇기에 컴파일은 빠르지만 실행시간이 느릴 수 있다. 동적 바인딩을 위한 주소를 담을 메모리를 미리 만들어 줘야한다.


가상함수 테이블


한 개 이상의 가상함수를 포함하는 클래스에 대해서는 컴파일러가 다음 가상함수 테이블을 만든다. 

이것을 V-Table(Virtual Table)이라고도 하는데, 이는 실제 호출되어야 할 함수의 위치정보를 담고 있는 테이블이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<iostream>
#include<string.h>
#include<string>
 
using namespace std;
 
 
class AAA {
private:
    int num1;
public:
    virtual void Func1() { cout << "Func1" << endl; }
    virtual void Func2() { cout << "Func2" << endl; }
};
 
class BBB : public AAA {
private:
    int num2;
public:
    virtual void Func1() { cout << "BBB::Func1" << endl; }
    void Func3() { cout << "Func3" << endl; }
};
 
int main() {
    AAA* aptr = new AAA();
    aptr->Func1();
 
    BBB* bptr = new BBB();
    bptr->Func1();
    return 0;
}
cs


위의 예제에서 가상함수를 포함하는 클래스에 대해 컴파일러는 가상함수 테이블을 생성한다.

가상함수 테이블은 실제 호출해야 할 함수의 위치정보를 가지고 있다.



key value                                 :: Class AAA

void AAA::Func1() 0x1024 번지

void AAA:Func2() 0x2048 번지



key value                                 :: Class BBB
void BBB::Func1() 0x3072 번지
void AAA:Func2() 0x2048 번지
void BBB:Func3() 0x4096 번지

AAA 클래스의 오버라이딩 된 가상함수 Func1(0x1024)에 대한 정보가 보이지 않는다.

오버라이딩 된 가상함수의 주소정보는 유도 클래스의 가상함수 테이블에 포함되지 않는다.
오버라이딩 된 가상함수를 호출하면, 무조건 가장 마지막에 오버라이딩을 한 유도 클래스의 멤버함수가 호출되는 것이다.

가상함수 테이블은 객체의 생성과 상관없이 메모리 공간에 할당 -> 맴버함수 호출에 사용되는 일종의 데이터이기 때문

위 코드에 다음 2줄을 추가하여 가상함수와 다형성 및 호출에 대해 생각해보면 좋을 것 같다.

1
2
3
4
5
6
 
    AAA *= new BBB();
    p->Func1();
    // 이 함수를 호출하면 AAA클래스의 함수가 아닌 BBB클래스의 함수가 호출됨
    // 가상함수에 의해 AAA클래스의 함수가 숨겨져버림
    // AAA클래스의 virtual키워드를 지우면 어떤 결과가 나올지 예상해보고 확인해보는ㄷ것도 좋다.
cs




'C , C++, C#' 카테고리의 다른 글

[C/C++] move  (0) 2019.11.14
[C/C++] 이동 생성자  (0) 2019.11.03
C++ 가상함수 이해정리  (0) 2019.03.06
C++ 함수 오버라이딩 간단정리  (0) 2019.03.06
C++ 다형성,상속 간단정리  (0) 2019.02.26