2012-04-08 2 views
2

가상 테이블에 의심의 여지가 있습니다. 컴파일러가 클래스에서 가상 함수를 발견하면 Vtable을 만들고 거기에 가상 함수 주소를 배치합니다. 상속받은 다른 클래스와 마찬가지로 발생합니다. 각 Vtable을 가리키는 각 클래스에 새로운 포인터가 생성됩니까? 파생 클래스의 새 인스턴스가 만들어져 Base PTR에 할당 될 때 Virtual 함수에 어떻게 액세스합니까?가상 함수의 Vtable 작동 방법

+0

가능한 복제본 [Virtual Table C++] (http://stackoverflow.com/questions/2173493/virtual-table-c) –

답변

1

가상 함수가있는 각 클래스에 대해 vtable이 만들어집니다. 그런 다음 생성자를 사용하여 실행 가능한 클래스의 객체를 만들면 해당 생성자가 해당 vtable을 객체에 복사합니다. 따라서 각 객체에는 해당 vtable에 대한 포인터가 있습니다 (또는 다중 상속의 경우 필요하면 각 vtable에 대한 Orr). 컴파일러는 객체의 vtable 위치를 알고 있으므로 가상 메소드를 호출해야 할 때 vtable을 억제하는 바이트 코드를 출력하고 적절한 메소드를 찾아 주소로 점프합니다.

단일 상속의 간단한 경우 자식 클래스는 부모 클래스의 vtable 복사본으로 시작한 다음 부모 클래스의 메서드를 재정의하는 자식 클래스의 각 가상 메서드에 대해 재정의 된 항목을 가져옵니다.

5

때마다 당신은 가상 함수를 포함하는 클래스를 생성 (그리고 그것은 또한 하지 재정의 부모 클래스의 방법을 수행하는 자식 클래드의 모든 가상 함수에 대한 새 항목을 얻는다), 또는 당신은 이 클래스에서 파생하는 가상 함수가 있으면 컴파일러 이 해당 클래스에 대해 고유 한 VTABLE을 만듭니다. 당신이 기본 클래스에서 가상 선언 한 함수를 재정의하지 경우

는 컴파일러는 파생 클래스에서 기본 클래스 버전의 주소를 사용합니다.

그런 다음 VPTR을 클래스에 넣습니다. 상속을 사용할 때 각 개체에 대해 하나의 VPTR 만 있습니다. VPTR은 해당 VTABLE의 시작 주소 인 을 가리 키도록 초기화해야합니다. (이것은 생성자에서 발생합니다.) VPTR이 적절한 VTABLE로 초기화되면 의 개체는 어떤 유형인지 알 수 있습니다. 그러나이 자체 지식은 가상 함수가 호출되는 지점에서 사용되지 않으면 쓸모가 없습니다. 기본 클래스 주소 (컴파일러에서 초기 바인딩을 수행하는 데 필요한 모든 정보 이없는 경우 상황)를 통해 가상 함수를 호출하면 특별한 현상이 발생합니다. 일반적인 주소 호출 (특정 주소에 대한 어셈블리 언어 CALL)을 수행하는 대신 컴파일러 은 함수 호출을 수행하는 다른 코드를 생성합니다.

+0

그렇다면 말을하는 것입니다. 오직 하나의 VPTR만이 객체 생성 중에 그리고 할당 권리 동안에는 특정 테이블을 가리킨다. 그러나 그것은 항상 기본 클래스에 존재할 것입니다. – Naruto

+0

내가 말했듯이, 컴파일러는 클래스와 파생 클래스에 대해 고유 한 VTABLE을 만듭니다. – IndieProgrammer

+0

VTABLE에 대한 VPTR은 어떻게됩니까? 파생 클래스를 인스턴스화하고 기본 ptr에 할당 할 때 어떻게 작동합니까? – Naruto

3

프로그램이 컴파일 될 때마다 각 클래스에 대한 가상 테이블이 만들어 지므로 vtable이 클래스별로 작성된다는 사실을 분명히합니다. 런타임 중에 개체가 만들어지면 컴파일러는 특정 클래스의 개체에 대한 가상 테이블을 가리키는 vptr을 개체에 할당합니다. 간단히 말해 vptr은 객체 단위로 생성됩니다.

관련 문제