开发者

Why are virtual methods considered early bound?

开发者 https://www.devze.com 2022-12-22 08:05 出处:网络
One definition of binding is that it is the act of replacing function names with memory addresses. a) Thus I assume early binding means function calls are replaced with memory addresses during compil

One definition of binding is that it is the act of replacing function names with memory addresses.

a) Thus I assume early binding means function calls are replaced with memory addresses during compilation process, while with late binding this replacement happens during runtime?

b) Why are virtual methods also considered early bound (thus the target method is found at compile time, and code is created that will call this method)? As far as I know, with virtual methods the call to actual method is resolved only during runtime and not compile time?!

thanx

EDIT:

1)

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

As far as I know, it is not known at compile time where on the heap (thus at which memory address ) will instance a be created during runtime. Now, with early binding the function calls开发者_C百科 are replaced with memory addresses during compilation process. But how can compiler replace function call with memory address, if it doesn’t know where on the heap will object a be created during runtime ( here I’m assuming the address of method a.M will also be at same memory location as a )?

2)

v-table calls are neither early nor late bound. Instead there's an offset into a table of function pointers. The offset is fixed at compile time, but which table the function pointer is chosen from depends on the runtime type of the object (the object contains a hidden pointer to its v-table), so the final function address is found at runtime.

But assuming the object of type T is created via reflection ( thus app doesn’t even know of existence of type T ), then how can at compile time exist an entry point for that type of object?


Late Binding

With late binding all you have is the name of the method. At compile time you have no way of known if the method even exists. This is known as "duck typing" in languages such as Ruby or Python.

Late binding is slow because you have to look up the function by name. It is also dangerous because you are not protected from minor spelling errors.

Prior to version 4, C# has no support for late binding aside from explicitly calling the reflection API.

Early Binding

When using early binding you compile against an actual method. This method may be referred to directly or it may be a slot in a V-table. Either way you are garunteed to not throw a MissingMethod exception.

History

Visual Basic was well known for supporting both early and late binding, but due it its other limitations it was never considered a true dynamic language. At the same time, versions prior to 7 (a.k.a. VB.NET) had very poor support for enforcing early binding, making it hard to call it a static language either.

With .NET 4, both C# and VB can be said to offer most features expected of both static and dynamically typed languages.

At one point Java was mistakenly said to have late binding support when it fact it only had early bound, OOP style V-tables. This has caused quite a bit on confusion over the years.


Virtual methods are early bound when the compiler knows the exact type at compile time.

If the compiler does not have the exact type it will generate a vtable lookup style late binding instead.


A call to a virtual method may be early bound as Joshua explains (i.e. the compiler can see the exact type of the object, no polymorphism going on), or it may be made through a v-table.

C# only does late binding when you use reflection (and in the next version, there's a new "dynamic" keyword to request late binding).

v-table calls are neither early nor late bound. Instead there's an offset into a table of function pointers. The offset is fixed at compile time, but which table the function pointer is chosen from depends on the runtime type of the object (the object contains a hidden pointer to its v-table), so the final function address is found at runtime.

EDIT to address new questions:

In (1) the entire premise is false. Functions aren't stored anywhere near the objects that "own" them. In fact, there's only one copy of the function for the entire program, and the object instance is passed as a hidden "this" parameter so the function knows which instance is being addressed.

For (2), there are two possibilities. One, the function call is done through reflection via a MethodInfo or such. This is truly late-bound. Two, the function call is made through an interface or base class which the caller knows at compile-time, even though the total type of the object isn't known. In this case a v-table call is used because the layout of the v-table is determined by the base class or interface, so the caller knows it and can predetermine the offset into the v-table.

0

精彩评论

暂无评论...
验证码 换一张
取 消