728x90
반응형
가상함수는 다형성을 구현하는 핵심 메커니즘으로, 객체지향 프로그래밍에서 중요한 역할을 한다.
비 가상함수는 성능이 중요한 경우에 선호되며, 가상함수는 유연한 설계가 필요한 경우에 사용된다.
이는 C++에서 중요한 개념이다.
호출 방식
비 가상 함수 | 정적 바인딩을 사용한다.staticbinding |
컴파일 시간에 어떤 함수를 호출할 지 결정된다.함수주소가컴파일시결정됨 | |
객체의 선언된 타입을 기준으로 함수가 호출된다. | |
가상 함수 | 동적 바인딩을 사용한다.dynamicbinding |
런타임에 어떤 함수를 호출할지 결정된다. | |
객체의 실제 타입을 기준으로 함수가 호출된다. |
메모리 구조
비 가상 함수 | 클래스의 모든 객체가 함수를 공유한다. |
별도의 메모리 공간에 위치하며, 객체 내부에 존재하지 않는다. | |
가상 함수 | 가상함수 테이블을 사용한다.vtable |
클래스에 가상함수가 하나라도 있으면 vtable이 생성된다. | |
각 객체는 vtable을 가리키는 포인터를 가진다. |
비 가상함수

가상함수

동작 원리
비 가상 함수
- 컴파일러가 객체의 선언된 타입을 확인
- 해당 타입의 클래스에 정의된 함수를 직접 호출
가상함수
- 객체의 vtable참조
- vtable에서 해당 함수의 주소 찾기
- 찾은 주소의 함수를 호출
가상함수의 실제 호출은 다음과 같이 변환된다.
- vtable
- 각 클래스 마다 생성되는 가상 테이블. 가상함수의 주소 저장
- 상속받은 가상함수가 오버라이딩 되면 파생 클래스의 함수 주소로 업데이트
- vptr
- 객체에 숨겨진 포인터, 해당 객체가 참조하는 클래스의 vtable주소
- 객체가 생성될 때 컴파일러가 vptr을 초기화
가상함수 호출 과정
- 객체 포인터ptr를 통해 vtable 접근
- vtable에서 호출할 함수 주소 검색
- 해당 함수의 주소로 이동하여 호출, 객체포인터 전달
ptr->VirtualFunc();
(*ptr->vptr[n])(ptr)
더보기
예제 코드
class Base {
public:
virtual void func() { std::cout << "Base\n"; }
};
class Derived : public Base {
public:
void func() override { std::cout << "Derived\n"; }
};
int main() {
Base* obj = new Derived();
obj->func(); // 가상 함수 호출
delete obj;
}
- obj->func는 컴파일러에 의해 다음과 같이 변환된다.
∗obj−>vptr[0]obj;
여기서 *obj->vptr : 객체 obj의 vtable
[0]은 vtable에서 첫번째 항목func() - 실행 시 obj는 실제로 Derived객체를 가리킨다. obj->vptr은 Derived클래스의 vtable을 참조한다.
- Derived의 vtable에서 첫 번째 항목은vptr[0]은 Derived::func의 주소를 가진다.
- ∗obj−>vptr[0]obj; 여기서 obj객체포인터를 전달하는 이유는 함수 내부에서 호출될 객체의 멤버변수에 접근해야하기 때문
성능과 유연성
비 가상 함수 | 호출 속도가 빠르다 |
컴파일 시간에 결정되어 최적화에 용이하다 | |
다형성을 지원하지 않는다 | |
가상 함수 | 호출 시 약간의 오버헤드가 발생한다. |
런타임 다형성을 지원하여 유연한 설계가 가능하다 | |
상속과 오버라이딩을 통한 확장성이 높다. |
728x90
반응형
'개발일지 > Unreal&C++' 카테고리의 다른 글
[Unreal] 언리얼 인터페이스, 그리고 장/단점 Interface 0 | 2025.04.03 |
---|---|
[Unreal] 오브젝트 그리고 CDOClassDefaultObject, generated.h, GENERATED_BODY 0 | 2025.04.01 |
[Unreal] 게임 플레이 프레임워크 0 | 2025.03.18 |
[Unreal] 서브 레벨 구성 및 스트리밍 레벨 로드 0 | 2025.03.18 |
[Unreal] Blueprint를 활용한 물체 충돌 구현, 효과 주기 0 | 2025.03.18 |