2010-03-10 3 views
4

바인딩의 정의 중 하나는 함수 이름을 메모리 주소로 바꾸는 행위라는 것입니다.가상 메서드가 초기 바인딩으로 간주되는 이유는 무엇입니까?

a) 따라서 초기 바인딩은 컴파일 프로세스 중에 함수 호출이 메모리 주소로 대체되었다고 가정합니다. 후기 바인딩을 사용하면 런타임에이 대체가 발생합니다.

b) 가상 메서드가 초기 바인딩으로 간주되는 이유 (따라서 대상 메서드가 컴파일 타임에 발견되어이 메서드를 호출하는 코드가 만들어 짐)? 지금까지 내가 아는 한, 가상 메소드를 사용하면 실제 메소드 호출은 런타임 중에 만 해결되고 컴파일 시간은 필요하지 않습니까?!

고맙습니다


편집 :

1) 지금까지 내가, 그것을 (따라서하는 경우 힙에 컴파일 타임에 알려져 있지 않다 알고

A a=new A(); 
a.M(); 

메모리 주소)는 실행 중에 인스턴스 a이 생성됩니다. 초기 바인딩을 사용하면 컴파일 과정에서 함수 호출이 메모리 주소로 대체됩니다. 하지만 컴파일러는 함수 호출을 메모리 주소로 대체 ​​할 수 있습니다. 실행시 힙이 어디에서 처리 될지 모르는 경우 (예 : 과 같은 메모리 위치에있는 메소드 a.M의 주소를 가정 할 때)?

2)

V-테이블 통화도 초기 나 바인딩 후반이다. 대신 함수 포인터 테이블에 오프셋이 있습니다. 오프셋은 컴파일 타임에 고정되지만 함수 포인터가 선택되는 테이블은 오브젝트의 런타임 유형에 따라 달라지며 (오브젝트에는 v 테이블에 대한 숨겨진 포인터가 포함됨) 최종 함수 주소가 런타임에 발견됩니다.

그러나 유형 T의 목적을 가정

이 반사를 통해 생성된다 (따라서 응용 프로그램도 유형 T의 존재를 알지 못한다), 그럼 어떻게 컴파일시에 객체의 유형에 대한 진입 점을 존재할 수 있습니까?

+0

적어도로드 시간까지 C#이 바인딩을하지 않기 때문에 C#이 올바른 태그인지 확신 할 수 없습니다. – Joshua

답변

1

가상 메소드는 컴파일러가 컴파일 할 때 정확한 유형을 알고있을 때 초기 바인딩됩니다.

컴파일러에 정확한 유형이없는 경우 대신 vtable 검색 스타일 후기 바인딩을 생성합니다.

6

늦은 늦은 바인딩으로

바인딩 당신이 가진 모든 메소드의 이름입니다. 컴파일 타임에 메서드가 존재하는 경우에도 알려진 방법이 없습니다. 이것은 루비 (Ruby) 나 파이썬 (Python)과 같은 언어로 "오리 타이핑 (duck typing)"이라고 알려져 있습니다.

이름으로 함수를 찾아야하기 때문에 후기 바인딩이 느립니다. 사소한 철자 오류로부터 보호받지 못하기 때문에 위험합니다.

버전 4 이전 버전에서 C#은 명시 적으로 리플렉션 API를 호출하는 것 외에 지연 바인딩을 지원하지 않습니다.

일찍 실제 방법에 대해 컴파일 초기 바인딩을 사용하는 경우

바인딩. 이 방법은 직접 참조하거나 V 테이블의 슬롯 일 수 있습니다. 어느 쪽이든 MissingMethod 예외를 throw하지 않도록주의하십시오.

역사

Visual Basic에서 잘 초기와 후기 바인딩,하지만 인해 다른 제한이 진정한 동적 언어로 간주되지 않았다 모두 지원 알려져 있었다. 동시에 7 이전의 버전 (VB.NET)에서는 초기 바인딩을 강제 적용하는 데 대한 지원이 매우 부족하여 정적 언어라고 부르기가 어려웠습니다.

.NET 4를 사용하면 C# 및 VB 모두 정적 유형 및 동적 유형 언어에서 기대되는 대부분의 기능을 제공한다고 말할 수 있습니다.

한때 자바는 OOP 스타일의 V-tables 만 가지고 있었을 때 늦게 바인딩 지원을한다고 잘못 말했습니다. 이것은 수년에 걸쳐 혼란을 일으켰습니다.

+0

안녕하세요, 저는 초기 게시물을 편집했습니다 ... 시간을 찾은 경우 – AspOnMyNet

1

가상 메소드 호출은 Joshua가 설명한대로 초기 바인딩 될 수 있습니다 (즉, 컴파일러가 객체의 정확한 유형을 볼 수 있고 다형성 현상은 나타나지 않음). 또는 v 테이블을 통해 만들 수 있습니다.

리플렉션을 사용하면 C#에서만 후기 바인딩이 수행됩니다 (다음 버전에서는 후기 바인딩을 요청하는 새로운 "동적"키워드가 있음).

v 테이블 호출은 초기 또는 후기 바인딩이 아닙니다. 대신 함수 포인터 테이블에 오프셋이 있습니다. 오프셋은 컴파일 타임에 고정되지만 함수 포인터가 선택되는 테이블은 오브젝트의 런타임 유형에 따라 달라지며 (오브젝트에는 v 테이블에 대한 숨겨진 포인터가 포함됨) 최종 함수 주소가 런타임에 발견됩니다.

편집은 새로운 질문을 해결하기 :

에서 (1) 전체 전제는 거짓입니다. 함수는 "소유 한"객체 근처에 저장되지 않습니다. 실제로 전체 프로그램에 대한 함수 복사본은 단 하나 뿐이며 개체 인스턴스는 숨겨진 "this"매개 변수로 전달되므로 함수는 어느 인스턴스가 처리되는지 알 수 있습니다.

(2)에는 두 가지 가능성이 있습니다. 첫째, 함수 호출은 MethodInfo 등을 통한 반영을 통해 수행됩니다. 이것은 정말로 늦은 바운드입니다. 둘째, 객체의 전체 유형을 알지 못하더라도 호출자가 컴파일 타임에 아는 인터페이스 또는 기본 클래스를 통해 함수 호출이 수행됩니다. 이 경우 v 테이블의 레이아웃은 기본 클래스 또는 인터페이스에 의해 결정되므로 호출자는이를 알고 v 테이블에 대한 오프셋을 미리 결정할 수 있으므로 v 테이블 호출이 사용됩니다.

+0

안녕하세요, 초기 게시물을 수정했습니다 ... 시간을 찾은 경우를 대비하여 – AspOnMyNet

+0

골동품 명명 규칙. vtable 조회는 C++에서 런타임에 바인딩하는 유일한 형식입니다. – Joshua

+0

함수 포인터는 v 테이블과 마찬가지로 늦기 때문에 어느 누구도 동적 링크만큼 늦지는 않습니다 (이는 표준화 된 C++ 언어의 일부는 아니지만 많은 수의 C++ 툴 체인에서 지원됨) –

관련 문제