가상함수는 어떻게 동작하는 것일까?
어떻게 객체가 컴파일때는 어떤 클래스인지 모르면서 함수 동작은 해당 클래스에 맞춰서 할 수 있는 것일까?
가상함수를 지원하는 C++은 C보다 살짝 더 느린데 왜그럴까?
가상함수의 동작원리에 대해 알아보도록 하자.
다음과 같은 C++ 코드가 있다고 가정해보자.
#include <iostream>
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(void)
{
AAA * aptr=new AAA();
aptr->Func1();
BBB * bptr=new BBB();
bptr->Func1();
return 0;
}
// 실행 결과
// Func1
// BBB::Func1
한 개 이상의 가상함수를 포함하는 클래스는 컴파일러가 '가상함수 테이블'이란 것을 만든다. 이는 실제 호출되어야 할 함수의 위치정보를 담고있는 테이블이다.
위 그림을 보면 BBB 가상함수 테이블에는 AAA 클래스의 오버라이딩 된 가상함수 Func1에 대한 정보가 존재하지 않는다는 걸 알 수 있다.
위 코드가 실행되면 main 함수가 호출되기 이전에 가상함수 테이블이 메모리 공간에 할당된다. 가상함수 테이블은 객체의 생성과 상관없이 메모리 공간에 할당된다. 이는 가상함수 테이블이 멤버함수의 호출에 사용되는 일종의 데이터이기 때문이다.
main함수에서 객체를 두개씩 생성한다면 다음과같이 참조 관계를 구성한다.
AAA 객체에서는 AAA클래스의 가상함수 테이블의 주소 값이 저장되고, BBB객체에는 BBB 클래스의 가상함수 테이블의 주소 값이 저장된다. 즉, 가상함수를 하나이상 맴버로 지니는 클래스의 객체에는 가상함수 테이블의 주소 값이 저장된다.
- 가상함수 테이블에 의한 속도 저하
클래스에 가상함수가 포함되면, 가상함수 테이블이 생성되고, 또 이 테이블을 참조하여 호출될 함수가 결정되기 때문에 실행속도가 감소한다. 그러나 그 속도의 차이가 극히 미미하고 또 이러한 단점에도 불구하고 가상함수는 많은 장점을 제공하기 때문에 유용하게 활용된다.
'공부 정리 > 이것저것' 카테고리의 다른 글
간단 시간복잡도 (0) | 2025.02.27 |
---|---|
C++ 기반 OOP 학습 정리 (0) | 2024.12.13 |
C와 파이썬을 활용한 NVIDIA GPU - 기초 문제 (0) | 2024.07.16 |
개발자는 어떤 종류가 있을까? (0) | 2024.05.27 |
IT 용어 정리 (0) | 2024.04.20 |