객체 안에 정말로 멤버함수가 존재하는가?

구조체 변수(객체)가 함수를 공유한다. 그리고 실제로 C++의 객체와 멤버함수는 이러한 관계를 갖는다. 즉, 멤버변수는 객체 내에 존재하지만, 멤버함수는 메모리의 한 공간에 별도로 위치하고선, 이함수가 정의된 클래스의 모든 객체가 이를 공유하는 형태를 취한다.

가상함수의 동작원리와 가상함수 테이블

가상함수의 동작원리를 이해하면, C++이 C보다 느린 이유를 조금이나마 알 수 있게 된다.

한개 이상의 가상함수를 포함하는 클래스에 대해서는 컴파일러가 다음 그림과 같은 형태의 ‘가상함수 테이블’이란것을 만든다. 이를 간단히 ‘V-Table(Virtual Table)’이라고도 하는데, 이는 실제 호출되어야 할 함수의 위치정보를 담고 있는 테이블이다.

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

“AAA 클래스의 오버라이딩 된 가상함수 Func1에 대한 정보가 존재하지 않는다.”

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

가상함수 테이블이 참조되는 방식

생성된 객체들은 각자 해당하는 클래스의 v-table 을 참조하게 된다.

가상함수 테이블에 의한 속도의 저하

위에서 설명했듯이 클래스에 가상함수가 포함되면, 가상함수 테이블이 생성되고, 또 이 테이블을 참조하여 호출될 함수가 결정되기 떄문에 실행속도가 감소하기 마련이다. 하지만 그 속도의 차이는 극히 미미하고 가상함수는 많은 장점을 제공하기 때문에 유용하게 활용되는 것이다.