C++에서 가상 함수는 다형성을 구현하는 데 매우 중요한 역할을 합니다.
일반 멤버 함수와 달리 가상 함수는 함수가 호출될 때 객체의 실제 유형을 기반으로 호출할 함수를 동적으로 바인딩합니다.
이는 런타임 다형성을 지원하며 개체의 동작을 유연하게 변경할 수 있습니다.
가상 함수를 사용하면 다형성을 지원하는 클래스의 인스턴스가 메모리에서 구성되는 방식을 관리하는 가상 테이블이 생성됩니다.
가상 테이블은 가상 함수에 대한 포인터를 저장하고 객체의 실제 유형과 일치하는 가상 함수를 호출합니다.
가상 함수와 가상 테이블을 사용하여 다형성을 구현함으로써 추상화, 캡슐화, 상속, 다형성과 같은 OOP 기능을 활용할 수 있습니다.
가상 테이블은 클래스 정의가 컴파일될 때 생성되며 각 클래스마다 하나씩 있습니다.
가상 테이블은 각 개체에 독립적으로 할당되며 개체의 가상 함수 호출은 해당 개체의 가상 함수 테이블을 통해 이루어집니다.
객체가 생성되면 가상 함수 포인터 테이블이 생성되고 해당 객체의 가상 함수에 대한 포인터가 테이블에 저장됩니다.
상속 관계에서 파생 클래스의 가상 함수 테이블은 기본 클래스의 가상 함수 테이블을 상속합니다.
파생 클래스가 기본 클래스의 가상 함수를 재정의하면 해당 함수에 대한 포인터가 파생 클래스의 가상 함수 테이블에 저장됩니다.
슈퍼클래스의 가상함수 대신 서브클래스에서 재정의된 가상함수를 호출하여 다형성을 구현할 수 있다.
따라서 클래스 정의 시 가상 테이블이 생성되고 해당 객체의 가상 함수 포인터 테이블을 통해 객체의 가상 함수 호출이 이루어지며, 상속 관계에서는 파생 클래스가 바탕 클래스의 가상 함수 테이블을 상속받게 되며,
재정의된 함수에 대한 포인터는 파생 클래스의 가상 함수 테이블에 저장됩니다.
스마트 포인터와의 관계
스마트 포인터 정보는 가상 테이블에 저장되지 않습니다.
(스마트 포인터는 C++에서 메모리 관리를 자동화하는 도구로 사용되며 포인터는 동적으로 할당된 객체를 처리합니다)
스마트 포인터는 개체의 수명을 관리하며 가상 테이블과 관련이 없습니다.
가상 테이블은 개체에 대한 가상 기능을 호출하는 메커니즘을 제공하는 데 사용되며 스마트 포인터는 개체의 수명을 관리하는 데 사용됩니다.
따라서 가상 테이블에는 가상 함수 포인터만 저장되고 스마트 포인터 정보는 저장되지 않습니다.
스마트 포인터를 사용하면 가상 함수가 호출될 때 개체가 여전히 유효한지 확인하는 데 사용할 수 있습니다.
이 경우 스마트 포인터는 가상 테이블과 독립적으로 사용됩니다.