**면접에서 가상함수가 무엇인지 가상함수 테이블의 생성 등에 대해 묻는 경우가 있다.**
가상함수의 특징은 동적 바인딩으로 컴파일이 아니고 프로그램이 실행, 함수가 호출될 때, 바인딩할 주소가 결정되는것
그렇기에 컴파일은 빠르지만 실행시간이 느릴 수 있다. 동적 바인딩을 위한 주소를 담을 메모리를 미리 만들어 줘야한다.
가상함수 테이블
한 개 이상의 가상함수를 포함하는 클래스에 대해서는 컴파일러가 다음 가상함수 테이블을 만든다.
이것을 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 *p = 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 |