[Basic C++] #18_오버라이딩의 특수한 경우 여섯 번째, 일반 메서드의 오버라이딩
C++ 개발에서 오버라이딩을 사용 시 주의할 점에 대해서 알아보겠습니다.
"전문가를 위한 C"의 9 항목, "클래스 상속 활용 테크닉"에 해당하는 내용입니다.
virtual의 내부 구현
"virtual" 키워드의 내부 구현에 대해서 알아보겠습니다.
컴파일러가 클래스의 정의 코드를 컴파일하면, 모든 멤버들이 들어 있는 바이너리 객체를 생성합니다.
이때, "virtual" 메서드가 아닌 경우, 호출 시 제어권의 전달이 컴파일 타임에 맞추어 직접 하드코딩됩니다.
반면에, "virtual" 메서드일 경우, 컴파일러는 "vtable"이라고 부르는 특별한 메모리 영역을 찾아보게 됩니다. "virtual" 메서드를 멤버로 갖고 있는 클래스는 자신만의 "vtable"을 통해 "virtual" 메서드의 구현부를 가리키는 포인터를 관리합니다.
만약, 어떤 객체의 "virtual" 메서드가 호출되면, 자신의 "vtable"에서 해당 메소드의 "오버라이딩"된 포인터를 찾아서, 객체의 실제 타입에 맞추어 적절한 메소드가 호출됩니다.
코드 예제
class Super
{
public:
virtual void func1() {}
virtual void func2() {}
void nonVirtualFunc() {}
};
class Sub : public Super
{
public:
virtual void func2() override {};
void nonVirtualFunc() {}
};
Super 클래스와 Sub 클래스 각각 자신만의 "vtable"에 대한 포인터들을 갖고 있습니다.
각 클래스와 "vtable"의 관계도를 위 그림을 통해 살펴보겠습니다.
Super 클래스의 "vtable"은 "func1"과 "func2"를 담고 있습니다.
이 둘은 각각 Super::func1"과 "Super::func2"를 가리키고 있습니다.
Sub 클래스 또한 "vtable"을 갖고 있습니다.
"Sub::func1"의 경우 오버라이딩 되지 않은, 즉 "Super::func1"을 그대로 호출하기 때문에,
Sub의 "vtable"이 담고 있는 "func1"에 대한 포인터는 "Super::func1"을 가리키고 있습니다.
반면에 "Sub::func2"는 "Super::func2"의 것을 오버라이딩하고 있기 때문에, "vtable"의 포인터는 Sub 클래스의 것을 그대로 가리키고 있습니다.
'언어 > Basic C++' 카테고리의 다른 글
[Basic C++] #21_가상 상속 (0) | 2022.05.01 |
---|---|
[Basic C++] #20_virtual 키워드, vtable 오버헤드 (0) | 2022.05.01 |
[Basic C++] #18_오버라이딩의 특수한 경우 여섯 번째, 일반 메소드의 오버라이딩 (0) | 2022.04.30 |
[Basic C++] #17_오버라이딩의 특수한 경우 다섯 번째, 복제 생성자, 대입 연산자 (0) | 2022.04.24 |
[Basic C++] #16_오버라이딩의 특수한 경우 네 번째, 디폴트 인자 값 (0) | 2022.04.03 |