2012-01-27 2 views
0

dynamic binding에서 함수 호출은 포인터가 가리키는 개체 유형을 기반으로 함수 구현에 바인딩됩니다. 기본 클래스 하위 객체의 포인터. 어떤 가상 함수 버전이 호출됩니까?

base *bptr = new derived; 
bptr->func(); 

함수 func 기본 클래스에서 가상 선언하자

우리는 다음과 같은 코드가 있다고 가정. 그런 다음 파생 클래스의 가상 함수 func 버전이 동적 바인딩으로 인해 런타임에 호출됩니다.

위의 개념을 이해합니다.

하지만 위의 개념을 연구 한 후에 다음과 같은 개념으로 혼란스러워했습니다.

위의 코드 조각에서 파생 클래스 개체에 대한 포인터는 암시 적으로 기본 클래스 개체에 대한 포인터로 변환됩니다. 그러면 bptr은 실제로 파생 클래스 객체의 기본 클래스 하위 객체를 가리키고 파생 클래스 객체를 가리 키지 않습니다.

기본 클래스 포인터 bptr이 기본 클래스 하위 객체를 가리키기 때문에 런타임 중에 기본 클래스의 가상 함수 버전 인 func을 호출하면 안됩니까? 이 예에서

답변

3

동적 바인딩 실제로 어떤 의미가없는 것 같습니다. 즉, 포인터 (정적)가 기본 하위 객체를 참조하는 경우에도 호출은 전체 객체의 (동적) 유형으로 전달됩니다.

일반적인 구현은 가상 함수 테이블을 사용합니다. 기본 하위 객체는 숨겨진 멤버로 자신이 속한 실제 완전한 유형의 가상 함수 테이블에 대한 포인터를 저장합니다. 가상 함수에 대한 모든 호출 (동적 디스패치가 비활성화되지 않음)은 최종 재정의가 호출되도록 추가 수준의 간접 참조를 통해 전달됩니다.

컴파일러는 테이블과 숨겨진 포인터를 관리하는 방법에 대해 가상 함수가있는 각 유형별로 테이블을 작성하고 그에 따라 포인터를 업데이트하는 코드를 다른 생성자에 주입합니다. 따라서 기본 하위 객체를 작성하는 동안 포인터는 기본 vtable을 참조하지만 파생 생성자를 입력하기 전에 삽입 된 코드는 파생 된 vtable을 참조하도록 포인터를 (기준으로) 업데이트합니다.

+0

David : 파생 클래스 객체의 vptr과 기본 클래스 하위 객체의 vptr이 모두 파생 클래스 VTABLE을 가리 킵니까? –

+0

@Linux - vptr은 객체가 실제로있는 유형의 vtable을 가리 킵니다. 여기에서 문제가되지 않는 객체를 가리 키기 위해 사용하는 포인터 *. –

+0

@LinuxPenseur : 파생 형식이 새로운 가상 함수를 선언하지 않는다고 가정하면 파생 된 vtable을 가리키는 기본 하위 개체에 저장된 단일 포인터가 있습니다. –

0

: 그것은 유도 객체 인스턴스를 가리키는 것처럼

base *bptr = new derived; 
bptr->func(); 

base 클래스는 단지 메소드가 호출 할 수있는 알 수있는 인터페이스로서 어떻게든지 사용된다. vtable (http://en.wikipedia.org/wiki/Virtual_method_table)은 derived 클래스의 메소드가 호출되도록합니다.

1

혼동하지 마십시오. "파생 클래스 개체에 대한 포인터는 기본 클래스 개체에 대한 포인터로 암시 적으로 변환됩니다."-이 문장의 의미는 derivedderivedOnly()이라는 메서드가 있다고 가정합니다.이 메서드는 base에 없습니다. 이제 bptr->derivedOnly();을 시도하면 실제로 derived의 객체를 참조하는 경우에도 오류가 발생합니다.

따라서 bptr은 실제로 base에 대한 포인터입니다.

관련 문제