I've recently read about the Dynamic Dispatch on Wikipedia and couldn't understand the difference between dynamic dispatch and late binding in C++.
When each one of the mechanisms is used?
The exact quote from Wikipedia:
Dynamic dispatch is different from late binding (also known as dynamic binding). In the context of selecting an operation, binding refers to the process of associating a name with an operation. Dispatching refers to choosing an implementation for the operation after you have decided which operation a name refers to. With dynamic dispatch, the name may be bound to a polymorphic operation at compile time, but the implementation not be chosen until runtime (this is how dynamic dispatch works in C++). However, late binding does imply dynamic dispatching since you cannot choose which implementation of a polymorphic operation to select until you have selected the operation that the name refers to.
A fairly decent answer to this is actually incorporated into a question on late vs. early binding on programmers.stackexchange.com.
In short, late binding refers to the object-side of an eval, dynamic dispatch refers to the functional-side. In late binding the type of a variable is the variant at runtime. In dynamic-dispatch, the function or subroutine being executed is the variant.
In C++, we don't really have late binding because the type is known (not necessarily the end of the inheritance hierarchy, but at least a formal base class or interface). But we do have dynamic dispatch via virtual methods and polymorphism.
The best example I can offer for late-binding is the untyped "object" in Visual Basic. The runtime environment does all the late-binding heavy lifting for you.
Dim obj
- initialize object then..
obj.DoSomething()
The compiler will actually code the appropriate execution context for the runtime-engine to perform a named lookup of the method called DoSomething, and if discovered with the properly matching parameters, actually execute the underlying call. In reality, something about the type of the object is known (it inherits from IDispatch and supports GetIDsOfNames(), etc). but as far as the language is concerned the type of the variable is utterly unknown at compile time, and it has no idea if DoSomething is even a method for whatever obj actually is until runtime reaches the point of execution.
I won't bother dumping a C++ virtual interface et'al, as I'm confident you already know what they look like. I hope it is obvious that the C++ language simply can't do this. It is strongly-typed. It can (and does, obviously) do dynamic dispatch via the polymorphic virtual method feature.
In C++, both are same.
In C++, there are two kinds of binding:
static binding — which is done at compile-time.
dynamic binding — which is done at runtime.
Dynamic binding, since it is done at runtime, is also referred to as late binding and static binding is sometime referred to as early binding.
Using dynamic-binding, C++ supports runtime-polymorphism through virtual functions (or function pointers), and using static-binding, all other functions calls are resolved.
Late binding is calling a method by name during runtime.
You don't really have this in c++, except for importing methods from a DLL.
An example for that would be: GetProcAddress()
With dynamic dispatch, the compiler has enough information to call the right implementation of the method. This is usually done by creating a virtual table.
The link itself explained the difference:
Dynamic dispatch is different from late binding (also known as dynamic binding). In the context of selecting an operation, binding refers to the process of associating a name with an operation. Dispatching refers to choosing an implementation for the operation after you have decided which operation a name refers to.
and
With dynamic dispatch, the name may be bound to a polymorphic operation at compile time, but the implementation not be chosen until runtime (this is how dynamic dispatch works in C++). However, late binding does imply dynamic dispatching since you cannot choose which implementation of a polymorphic operation to select until you have selected the operation that the name refers to.
But they're mostly equal in C++ you can do a dynamic dispatch by virtual functions and vtables.
C++ uses early binding and offers both dynamic and static dispatch. The default form of dispatch is static. To get dynamic dispatch you must declare a method as virtual.
Binding refers to the process of associating a name with an operation.
the main thing here is function parameters these decides which function to call at runtime
Dispatching refers to choosing an implementation for the operation after you have decided which operation a name refers to.
dispatch control to that according to parameter match
http://en.wikipedia.org/wiki/Dynamic_dispatch
hope this help you
Let me give you an example of the differences because they are NOT the same. Yes, dynamic dispatch lets you choose the correct method when you are referring to an object by a superclass, but that magic is very specific to that class hierarchy, and you have to do some declarations in the base class to make it work (abstract methods fill out the vtables since the index of the method in the table cant change between specific types). So, you can call methods in Tabby and Lion and Tiger all by a generic Cat pointer and even have arrays of Cats filled with Lions and Tigers and Tabbys. It knows what indexes those methods refer to in the object's vtable at compile-time (static/early binding), even though the method is selected at run-time (dynamic dispatch).
Now, lets implement an array that contains Lions and Tigers and Bears! ((Oh My!)). Assuming we don't have a base class called Animal, in C++, you are going to have significant work to do to because the compiler isn't going to let you do any dynamic dispatch without a common base class. The indexes for the vtables need to match up, and that can't be done between unreleated classes. You'd need to have a vtable big enough to hold the virtual methods of all classes in the system. C++ programmers rarely see this as a limitation because you have been trained to think a certain way about class design. I'm not saying its better or worse.
With late binding, the run-time takes care of this without a common base class. There is normally a hash table system used to find methods in the classes with a cache system used in the dispatcher. Where in C++, the compiler knows all the types. In a late-bound language, the objects themselves know their type (its not typeless, the objects themselves know exactly who they are in most cases). This means I can have arrays of multiple types of objects if I want (Lions and Tigers and Bears). And you can implement message forwarding and prototyping (allows behaviors to be changed per object without changing the class) and all sorts of other things in ways that are much more flexible and lead to less code overhead than in languages that don't support late binding.
Ever program in Android and use findViewById()? You almost always end up casting the result to get the right type, and casting is basically lying to the compiler and giving up all the static type-checking goodness that is supposed to make static languages superior. Of course, you could instead have findTextViewById(), findEditTextById(), and a million others so that your return types match, but that is throwing polymorphism out the window; arguably the whole basis of OOP. A late-bound language would probably let you simply index by an ID, and treat it like a hash table and not care what the type was being indexed nor returned.
Here's another example. Let's say that you have your Lion class and its default behavior is to eat you when you see it. In C++, if you wanted to have a single "trained" lion, you need to make a new subclass. Prototyping would let you simply change the one or two methods of that particular Lion that need to be changed. It's class and type don't change. C++ can't do that. This is important since when you have a new "AfricanSpottedLion" that inherits from Lion, you can train it too. The prototyping doesn't change the class structure so it can be expanded. This is normally how these languages handle issues that normally require multiple inheritance, or perhaps multiple inheritance is how you handle a lack of prototyping.
FYI, Objective-C is C with SmallTalk's message passing added and SmallTalk is the original OOP, and both are late bound with all the features above and more. Late bound languages may be slightly slower from a micro-level standpoint, but can often allow the code to structured in a way that is more efficient at a macro-level, and it all boils down to preference.
Given that wordy Wikipedia definition I'd be tempted to classify dynamic dispatch as the late binding of C++
struct Base {
virtual void foo(); // Dynamic dispatch according to Wikipedia definition
void bar(); // Static dispatch according to Wikipedia definition
};
Late binding instead, for Wikipedia, seems to mean pointer-to-member dispatch of C++
(this->*mptr)();
where the selection of what is the operation being invoked (and not just which implementation) is done at runtime.
In C++ literature however late binding is normally used for what Wikipedia calls dynamic dispatch.
Dynamic dispatch is what happens when you use the virtual keyword in C++. So for example:
struct Base
{
virtual int method1() { return 1; }
virtual int method2() { return 2; } // not overridden
};
struct Derived : public Base
{
virtual int method1() { return 3; }
}
int main()
{
Base* b = new Derived;
std::cout << b->method1() << std::endl;
}
will print 3, because the method has been dynamically dispatched. The C++ standard is very careful not to specify how exactly this happens behind the scenes, but every compiler under the sun does it in the same way. They create a table of function pointers for each polymorphic type (called the virtual table or vtable), and when you call a virtual method, the "real" method is looked up from the vtable, and that version is called. So you can imaging something like this pseudocode:
struct BaseVTable
{
int (*_method1) () = &Base::method1; // real function address
int (*_method2) () = &Base::method2;
};
struct DerivedVTable
{
int (*method1) () = &Derived::method1; //overriden
int (*method2) () = &Base::method2; // not overridden
};
In this way, the compiler can be sure that a method with a particular signature exists at compile time. However, at run-time, the call might actually be dispatched via the vtable to a different function. Calls to virtual functions are a tiny bit slower than non-virtual calls, because of the extra indirection step.
On the other hand, my understanding of the term late binding is that the function pointer is looked up by name at runtime, from a hash table or something similar. This is the way things are done in Python, JavaScript and (if memory serves) Objective-C. This makes it possible to add new methods to a class at run-time, which cannot directly be done in C++. This is particularly useful for implementing things like mixins. However, the downside is that the run-time lookup is generally considerably slower than even a virtual call in C++, and the compiler is not able to perform any compile-time type checking for the newly-added methods.
This question might help you.
Dynamic dispatch generally refers to multiple dispatch.
Consider the below example. I hope it might help you.
class Base2;
class Derived2; //Derived2 class is child of Base2
class Base1 {
public:
virtual void function1 (Base2 *);
virtual void function1 (Derived2 *);
}
class Derived1: public Base1 {
public:
//override.
virtual void function1(Base2 *);
virtual void function1(Derived2 *);
};
Consider the case of below.
Derived1 * d = new Derived1;
Base2 * b = new Derived2;
//Now which function1 will be called.
d->function1(b);
It will call function1 taking Base2* not Derived2*. This is due to lack of dynamic multiple dispatch.
Late binding is one of the mechanism to implement dynamic single dispatch.
I suppose the meaning is when you have two classes B,C inherits the same father class A. so, pointer of the father (type A) can hold each of sons types. The compiler cannot know what the type holds in the pointer in certain time, because it can change during the program run.
There is special functions to determine what the type of certain object in certain time. like instanceof in java, or by if(typeid(b) == typeid(A))... in c++.
In C++, both dynamic dispatch and late binding is the same. Basically, the value of a single object determines the piece of code invoked at runtime. In languages like C++ and java dynamic dispatch is more specifically dynamic single dispatch which works as mentioned above. In this case, since the binding occurs at runtime, it is also called late binding. Languages like smalltalk allow dynamic multiple dispatch in which the runtime method is chosen at runtime based on the identities or values of more than one object.
In C++ we dont really have late binding, because the type information is known. Thus in the C++ or Java context, dynamic dispatch and late binding are the same. Actual/fully late binding, I think is in languages like python which is a method-based lookup rather than type based.
Related
I am trying to understand the concept of virtual functions. According to Wikipedia:
In short, a virtual function defines a target function to be executed,
but the target might not be known at compile time.
My question is, how is this different from conditional execution?
void conditional_func(func_to_run) {
switch(func_to_run) {
case func1_tag: func1(); break;
case func1_tag: func1(); break;
...
}
}
int main() {
read func_to_run
conditional_func(func_to_run)
}
As you can see the ultimate target of the conditional_func is not known at runtime.
In C++, it seems that virtual function is defined as a facility to allow for "polymorphism". My definition of polymorphism: A polymorphic class is a class with objects that can have different forms (morphology) as opposed to having a static form. That is, the objects can have different actions and properties based on their subclass. (I'm avoiding mention of language specific concepts like pointers in my definition)
Therefore what is called a virtual function in C++ does not even have to be dependent on dynamic binding (runtime resolution of the target function), but can have a known target at compile time:
int main()
{
Drived d;
Base *bPtr = &d;
bPtr->func();
}
In the above example, the compiler knows that the Base pointer is pointing at a Derived object, and therefore will know the target address for the version of func to run. Therefore my conclusion is that what Wikipedia refers to as a virtual function, is the same as C++ virtual functions that are for some reason dynamically bound:
int main()
{
Drived1 d1;
Drived2 d2;
read val;
if (val == 1) Base *bPtr = &d1;
else Base *bPtr = &d2;
bPtr->func();
}
As you can see this is also just conditional execution. So here are my questions:
1) If virtual function is defined as a function with unknown target at compile time, how is this different than conditional execution? Are they the same in assembly level but different at higher layers of abstraction?
2) If virtual function is defined as a facility to allow for polymorphism as defined above, then does it mean that again it is only a concept of higher level languages?
1) If virtual function is defined as a function with unknown target at compile time, how is this different than conditional execution? Are they the same in assembly level but different at higher layers of abstraction?
At the assembly/machine code level, virtual functions are typically implemented as class-specific tables of function pointers (known as Virtual Dispatch Tables or VDTs), with each object of those types having a pointer to its class's table. The layout of these tables is consistent across base and derived classes such that given a pointer to any object in the heirarchy, the function pointer for any given virtual function is always at the same position in all the classes' VDTs. This means the same machine code can take the object pointer and find the function to call.
A difference from the type of switch based code you illustrate in that all code with such switches would need to be manually updated and recompiled to support more types. With function pointers, new code for new types can simply be linked to existing code that works via pointers, without the latter being changed or recompiled.
2) If virtual function is defined as a facility to allow for polymorphism as defined above, then does it mean that again it is only a concept of higher level languages?
Firstly, your attempt to define polymorphism is not consistent with C++ terminology. You've got:
A polymorphic class is a class with objects that can have different forms (morphology) as opposed to having a static form. That is, the objects can have different actions and properties based on their subclass.
It'd be closer to the truth in C++ to say that any given class has one form, and it's different classes in an inheritance heirarchy that may have different forms / actions / properties.
Onwards. At the machine code level, you can - obviously given C++ has to output machine code - use function pointers and get the same runtime effect as virtual functions.
What virtual functions add is the convenience and reliability of having the compiler doing much of the work for you:
create virtual-dispatch tables,
ensuring consistent ordering of function pointers,
giving objects an implicit pointers to these tables and initialising it reliably in the first non-abstract-base's constructor and updating it as construction bubbles down the class heirarchy to the actual object's runtime type, then reversing the value of the pointer as destructors kick in,
checking that overrides have the same function signature as the virtual functions they override,
optionally optimising away runtime dispatch when the called function can be deduced at compile time.
Such assurances and compiler-generated actions makes C++-style virtual functions and dispatch a higher level language feature than programmer-coordinated use of function pointers, let alone switches on runtime type. That said, there's nothing in particular stopping someone adding such support to an assembly language. That said, many languages that are on balance even higher level than C++ lack anything similar to virtual functions. (At the extreme, a 5GL may not even expose a notion of functions to the "programmer"/user).
I recently I came across a C++ interview question which got me very intrigued:
Suppose you declare mistakenly some C++ member function as virtual, but (maybe for performance reasons) you want to prevent the compiler from creating a v-table for this function. That is, disable thee dynamic function binding in favor of a static binding.
How would you achieve this? Also, are there some C++11 specific ways of doing so?
I'm aware of no way to coerce a C++ compiler to disable dynamic binding, short of forcing it to compile code purely as C if it supports such an option (which not all C++ compilers do, but most do). However, that is sort of throwing out the baby with the bathwater, as it notionally disables all C++ features that are not part of C.
There is, of course, the final identifier introduced in C++11, which prevents further derivation from a class or overriding of virtual members. Strictly speaking, this does not prevent dynamic dispatch though - it addresses a different problem.
One way to avoid implications (perceived or actual) of dynamic binding is to avoid using or writing any classes with virtual member functions, and to not create a class hierarchy (i.e. don't derive from classes with virtual functions). Clearly, if there are no virtual functions in play, there is no need for virtual function dispatch, and therefore no need for dynamic binding.
If you know the type of an object, it is possible to avoid use of dynamic binding by using static dispatch i.e. explicitly naming which function to call. For example, let's say we have a class Base that provides a public virtual member named foo() and a class named Derived that inherits from Base and overrides foo(). Then the following avoids doing dynamic dispatch;
Base *b = new Derived;
b->Base::foo(); // static call; will not call `Derived::foo()`
b->Derived::Foo(); // incorrect static call. Will not compile since b is a pointer to Base not Derived
Derived *d = new Derived;
d->Derived::foo(); // static call of Derived::foo()
d->Base::foo(); // static call of Base::foo()
Of course, if the code which uses an object relies on knowledge of the ACTUAL type of an object, or on a specific variant of foo() being called, then its design sort-of defeats the purpose of having a polymorphic base class and other classes that derive from it.
In the above, the compiler will still support virtual function calls (vtable, etc, if that is now the compiler works) and that may affect the process of creating and destroying objects.
Another technique to avoid dynamic dispatch (or binding) is to use templates (sometimes called compile-time polymorphism). Essentially, the template may assume a type provides some interface (or set of operations) and will work with any variable of a type with that interface. For example;
struct X
{
void foo();
};
template<class T> void func()
{
T x; // relies on T being instantiable (and destructible)
x.foo(); // relies on T having a member named foo()
}
// in some function somewhere where both X and func() are known to the compiler
func<X>();
Such templates do not need the type T to have virtual functions, so do not rely on dynamic dispatch (binding). However, there is nothing stopping such a template function working with a class that has virtual member functions, so this does not disable dynamic binding - it only allows the programmer to make choices to avoid using dynamic binding.
If I was asked this question in interview, I'd probably point out all of the above, but leave it unsaid that the question is rather silly. An interviewer knowledgeable about C++ will realise that, and just be interested in how you think through and address such a question (after all real-world developers are often asked by management or customers to meet silly or unrealistic requirements, and are expected to be tactful enough to avoid telling their managers or customers they are being foolish). If the interviewer has asked the question without understanding that (or without another member of the interview panel who understands that in the room) I wouldn't want to work with that employer anyway.
you could avoid the overhead by disabling RTTI...there is a compile time switch for that.
There wont be any overhead of virtual table dispatch, for dynamic_cast/typeid once RTTI disable flag is enabled.
Coming from Delphi, I'm used to using class references (metaclasses) like this:
type
TClass = class of TForm;
var
x: TClass;
f: TForm;
begin
x := TForm;
f := x.Create();
f.ShowModal();
f.Free;
end;
Actually, every class X derived from TObject have a method called ClassType that returns a TClass that can be used to create instances of X.
Is there anything like that in C++?
Metaclasses do not exist in C++. Part of why is because metaclasses require virtual constructors and most-derived-to-base creation order, which are two things C++ does not have, but Delphi does.
However, in C++Builder specifically, there is limited support for Delphi metaclasses. The C++ compiler has a __classid() and __typeinfo() extension for retrieving a Delphi-compatible TMetaClass* pointer for any class derived from TObject. That pointer can be passed as-is to Delphi code (you can use Delphi .pas files in a C++Builder project).
The TApplication::CreateForm() method is implemented in Delphi and has a TMetaClass* parameter in C++ (despite its name, it can actually instantiate any class that derives from TComponent, if you do not mind the TApplication object being assigned as the Owner), for example:
TForm *f;
Application->CreateForm(__classid(TForm), &f);
f->ShowModal();
delete f;
Or you can write your own custom Delphi code if you need more control over the constructor call:
unit CreateAFormUnit;
interface
uses
Classes, Forms;
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
implementation
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
begin
Result := AClass.Create(AOwner);
end;
end.
#include "CreateAFormUnit.hpp"
TForm *f = CreateAForm(__classid(TForm), SomeOwner);
f->ShowModal();
delete f;
Apparently modern Delphi supports metaclasses in much the same way as original Smalltalk.
There is nothing like that in C++.
One main problem with emulating that feature in C++, having run-time dynamic assignment of values that represent type, and being able to create instances from such values, is that in C++ it's necessary to statically know the constructors of a type in order to instantiate.
Probably you can achieve much of the same high-level goal by using C++ static polymorphism, which includes function overloading and the template mechanism, instead of extreme runtime polymorphism with metaclasses.
However, one way to emulate the effect with C++, is to use cloneable exemplar-objects, and/or almost the same idea, polymorphic object factory objects. The former is quite unusual, the latter can be encountered now and then (mostly the difference is where the parameterization occurs: with the examplar-object it's that object's state, while with the object factory it's arguments to the creation function). Personally I would stay away from that, because C++ is designed for static typing, and this idea is about cajoling C++ into emulating a language with very different characteristics and programming style etc.
Type information does not exist at runtime with C++. (Except when enabling RTTI but it is still different than what you need)
A common idiom is to create a virtual clone() method that obviously clones the object which is usually in some prototypical state. It is similar to a constructor, but the concrete type is resolved at runtime.
class Object
{
public:
virtual Object* clone() const = 0;
};
If you don't mind spending some time examining foreign sources, you can take a look at how a project does it: https://github.com/rheit/zdoom/blob/master/src/dobjtype.h (note: this is a quite big and evolving source port of Doom, so be advised even just reading will take quite some time). Look at PClass and related types. I don't know what is done here exactly, but from my limited knowledge they construct a structure with necessary metatable for each class and use some preprocessor magic in form of defines for readability (or something else). Their approach allows seamlessly create usual C++ classes, but adds support for PClass::FindClass("SomeClass") to get the class reference and use that as needed, for example to create an instance of the class. It also can check inheritance, create new classes on the fly and replace classes by others, i. e. you can replace CDoesntWorksUnderWinXP by CWorksEverywhere (as an example, they use it differently of course). I had a quick research back then, their approach isn't exceptional, it was explained on some sites but since I had only so much interest I don't remember details.
I've recently read about the Dynamic Dispatch on Wikipedia and couldn't understand the difference between dynamic dispatch and late binding in C++.
When each one of the mechanisms is used?
The exact quote from Wikipedia:
Dynamic dispatch is different from late binding (also known as dynamic binding). In the context of selecting an operation, binding refers to the process of associating a name with an operation. Dispatching refers to choosing an implementation for the operation after you have decided which operation a name refers to. With dynamic dispatch, the name may be bound to a polymorphic operation at compile time, but the implementation not be chosen until runtime (this is how dynamic dispatch works in C++). However, late binding does imply dynamic dispatching since you cannot choose which implementation of a polymorphic operation to select until you have selected the operation that the name refers to.
A fairly decent answer to this is actually incorporated into a question on late vs. early binding on programmers.stackexchange.com.
In short, late binding refers to the object-side of an eval, dynamic dispatch refers to the functional-side. In late binding the type of a variable is the variant at runtime. In dynamic-dispatch, the function or subroutine being executed is the variant.
In C++, we don't really have late binding because the type is known (not necessarily the end of the inheritance hierarchy, but at least a formal base class or interface). But we do have dynamic dispatch via virtual methods and polymorphism.
The best example I can offer for late-binding is the untyped "object" in Visual Basic. The runtime environment does all the late-binding heavy lifting for you.
Dim obj
- initialize object then..
obj.DoSomething()
The compiler will actually code the appropriate execution context for the runtime-engine to perform a named lookup of the method called DoSomething, and if discovered with the properly matching parameters, actually execute the underlying call. In reality, something about the type of the object is known (it inherits from IDispatch and supports GetIDsOfNames(), etc). but as far as the language is concerned the type of the variable is utterly unknown at compile time, and it has no idea if DoSomething is even a method for whatever obj actually is until runtime reaches the point of execution.
I won't bother dumping a C++ virtual interface et'al, as I'm confident you already know what they look like. I hope it is obvious that the C++ language simply can't do this. It is strongly-typed. It can (and does, obviously) do dynamic dispatch via the polymorphic virtual method feature.
In C++, both are same.
In C++, there are two kinds of binding:
static binding — which is done at compile-time.
dynamic binding — which is done at runtime.
Dynamic binding, since it is done at runtime, is also referred to as late binding and static binding is sometime referred to as early binding.
Using dynamic-binding, C++ supports runtime-polymorphism through virtual functions (or function pointers), and using static-binding, all other functions calls are resolved.
Late binding is calling a method by name during runtime.
You don't really have this in c++, except for importing methods from a DLL.
An example for that would be: GetProcAddress()
With dynamic dispatch, the compiler has enough information to call the right implementation of the method. This is usually done by creating a virtual table.
The link itself explained the difference:
Dynamic dispatch is different from late binding (also known as dynamic binding). In the context of selecting an operation, binding refers to the process of associating a name with an operation. Dispatching refers to choosing an implementation for the operation after you have decided which operation a name refers to.
and
With dynamic dispatch, the name may be bound to a polymorphic operation at compile time, but the implementation not be chosen until runtime (this is how dynamic dispatch works in C++). However, late binding does imply dynamic dispatching since you cannot choose which implementation of a polymorphic operation to select until you have selected the operation that the name refers to.
But they're mostly equal in C++ you can do a dynamic dispatch by virtual functions and vtables.
C++ uses early binding and offers both dynamic and static dispatch. The default form of dispatch is static. To get dynamic dispatch you must declare a method as virtual.
Binding refers to the process of associating a name with an operation.
the main thing here is function parameters these decides which function to call at runtime
Dispatching refers to choosing an implementation for the operation after you have decided which operation a name refers to.
dispatch control to that according to parameter match
http://en.wikipedia.org/wiki/Dynamic_dispatch
hope this help you
Let me give you an example of the differences because they are NOT the same. Yes, dynamic dispatch lets you choose the correct method when you are referring to an object by a superclass, but that magic is very specific to that class hierarchy, and you have to do some declarations in the base class to make it work (abstract methods fill out the vtables since the index of the method in the table cant change between specific types). So, you can call methods in Tabby and Lion and Tiger all by a generic Cat pointer and even have arrays of Cats filled with Lions and Tigers and Tabbys. It knows what indexes those methods refer to in the object's vtable at compile-time (static/early binding), even though the method is selected at run-time (dynamic dispatch).
Now, lets implement an array that contains Lions and Tigers and Bears! ((Oh My!)). Assuming we don't have a base class called Animal, in C++, you are going to have significant work to do to because the compiler isn't going to let you do any dynamic dispatch without a common base class. The indexes for the vtables need to match up, and that can't be done between unreleated classes. You'd need to have a vtable big enough to hold the virtual methods of all classes in the system. C++ programmers rarely see this as a limitation because you have been trained to think a certain way about class design. I'm not saying its better or worse.
With late binding, the run-time takes care of this without a common base class. There is normally a hash table system used to find methods in the classes with a cache system used in the dispatcher. Where in C++, the compiler knows all the types. In a late-bound language, the objects themselves know their type (its not typeless, the objects themselves know exactly who they are in most cases). This means I can have arrays of multiple types of objects if I want (Lions and Tigers and Bears). And you can implement message forwarding and prototyping (allows behaviors to be changed per object without changing the class) and all sorts of other things in ways that are much more flexible and lead to less code overhead than in languages that don't support late binding.
Ever program in Android and use findViewById()? You almost always end up casting the result to get the right type, and casting is basically lying to the compiler and giving up all the static type-checking goodness that is supposed to make static languages superior. Of course, you could instead have findTextViewById(), findEditTextById(), and a million others so that your return types match, but that is throwing polymorphism out the window; arguably the whole basis of OOP. A late-bound language would probably let you simply index by an ID, and treat it like a hash table and not care what the type was being indexed nor returned.
Here's another example. Let's say that you have your Lion class and its default behavior is to eat you when you see it. In C++, if you wanted to have a single "trained" lion, you need to make a new subclass. Prototyping would let you simply change the one or two methods of that particular Lion that need to be changed. It's class and type don't change. C++ can't do that. This is important since when you have a new "AfricanSpottedLion" that inherits from Lion, you can train it too. The prototyping doesn't change the class structure so it can be expanded. This is normally how these languages handle issues that normally require multiple inheritance, or perhaps multiple inheritance is how you handle a lack of prototyping.
FYI, Objective-C is C with SmallTalk's message passing added and SmallTalk is the original OOP, and both are late bound with all the features above and more. Late bound languages may be slightly slower from a micro-level standpoint, but can often allow the code to structured in a way that is more efficient at a macro-level, and it all boils down to preference.
Given that wordy Wikipedia definition I'd be tempted to classify dynamic dispatch as the late binding of C++
struct Base {
virtual void foo(); // Dynamic dispatch according to Wikipedia definition
void bar(); // Static dispatch according to Wikipedia definition
};
Late binding instead, for Wikipedia, seems to mean pointer-to-member dispatch of C++
(this->*mptr)();
where the selection of what is the operation being invoked (and not just which implementation) is done at runtime.
In C++ literature however late binding is normally used for what Wikipedia calls dynamic dispatch.
Dynamic dispatch is what happens when you use the virtual keyword in C++. So for example:
struct Base
{
virtual int method1() { return 1; }
virtual int method2() { return 2; } // not overridden
};
struct Derived : public Base
{
virtual int method1() { return 3; }
}
int main()
{
Base* b = new Derived;
std::cout << b->method1() << std::endl;
}
will print 3, because the method has been dynamically dispatched. The C++ standard is very careful not to specify how exactly this happens behind the scenes, but every compiler under the sun does it in the same way. They create a table of function pointers for each polymorphic type (called the virtual table or vtable), and when you call a virtual method, the "real" method is looked up from the vtable, and that version is called. So you can imaging something like this pseudocode:
struct BaseVTable
{
int (*_method1) () = &Base::method1; // real function address
int (*_method2) () = &Base::method2;
};
struct DerivedVTable
{
int (*method1) () = &Derived::method1; //overriden
int (*method2) () = &Base::method2; // not overridden
};
In this way, the compiler can be sure that a method with a particular signature exists at compile time. However, at run-time, the call might actually be dispatched via the vtable to a different function. Calls to virtual functions are a tiny bit slower than non-virtual calls, because of the extra indirection step.
On the other hand, my understanding of the term late binding is that the function pointer is looked up by name at runtime, from a hash table or something similar. This is the way things are done in Python, JavaScript and (if memory serves) Objective-C. This makes it possible to add new methods to a class at run-time, which cannot directly be done in C++. This is particularly useful for implementing things like mixins. However, the downside is that the run-time lookup is generally considerably slower than even a virtual call in C++, and the compiler is not able to perform any compile-time type checking for the newly-added methods.
This question might help you.
Dynamic dispatch generally refers to multiple dispatch.
Consider the below example. I hope it might help you.
class Base2;
class Derived2; //Derived2 class is child of Base2
class Base1 {
public:
virtual void function1 (Base2 *);
virtual void function1 (Derived2 *);
}
class Derived1: public Base1 {
public:
//override.
virtual void function1(Base2 *);
virtual void function1(Derived2 *);
};
Consider the case of below.
Derived1 * d = new Derived1;
Base2 * b = new Derived2;
//Now which function1 will be called.
d->function1(b);
It will call function1 taking Base2* not Derived2*. This is due to lack of dynamic multiple dispatch.
Late binding is one of the mechanism to implement dynamic single dispatch.
I suppose the meaning is when you have two classes B,C inherits the same father class A. so, pointer of the father (type A) can hold each of sons types. The compiler cannot know what the type holds in the pointer in certain time, because it can change during the program run.
There is special functions to determine what the type of certain object in certain time. like instanceof in java, or by if(typeid(b) == typeid(A))... in c++.
In C++, both dynamic dispatch and late binding is the same. Basically, the value of a single object determines the piece of code invoked at runtime. In languages like C++ and java dynamic dispatch is more specifically dynamic single dispatch which works as mentioned above. In this case, since the binding occurs at runtime, it is also called late binding. Languages like smalltalk allow dynamic multiple dispatch in which the runtime method is chosen at runtime based on the identities or values of more than one object.
In C++ we dont really have late binding, because the type information is known. Thus in the C++ or Java context, dynamic dispatch and late binding are the same. Actual/fully late binding, I think is in languages like python which is a method-based lookup rather than type based.
This is not a question about how they work and declared, this I think is pretty much clear to me. The question is about why to implement this?
I suppose the practical reason is to simplify bunch of other code to relate and declare their variables of base type, to handle objects and their specific methods from many other subclasses?
Could this be done by templating and typechecking, like I do it in Objective C? If so, what is more efficient? I find it confusing to declare object as one class and instantiate it as another, even if it is its child.
SOrry for stupid questions, but I havent done any real projects in C++ yet and since I am active Objective C developer (it is much smaller language thus relying heavily on SDK's functionalities, like OSX, iOS) I need to have clear view on any parallel ways of both cousins.
Yes, this can be done with templates, but then the caller must know what the actual type of the object is (the concrete class) and this increases coupling.
With virtual functions the caller doesn't need to know the actual class - it operates through a pointer to a base class, so you can compile the client once and the implementor can change the actual implementation as much as it wants and the client doesn't have to know about that as long as the interface is unchanged.
Virtual functions implement polymorphism. I don't know Obj-C, so I cannot compare both, but the motivating use case is that you can use derived objects in place of base objects and the code will work. If you have a compiled and working function foo that operates on a reference to base you need not modify it to have it work with an instance of derived.
You could do that (assuming that you had runtime type information) by obtaining the real type of the argument and then dispatching directly to the appropriate function with a switch of shorts, but that would require either manually modifying the switch for each new type (high maintenance cost) or having reflection (unavailable in C++) to obtain the method pointer. Even then, after obtaining a method pointer you would have to call it, which is as expensive as the virtual call.
As to the cost associated to a virtual call, basically (in all implementations with a virtual method table) a call to a virtual function foo applied on object o: o.foo() is translated to o.vptr[ 3 ](), where 3 is the position of foo in the virtual table, and that is a compile time constant. This basically is a double indirection:
From the object o obtain the pointer to the vtable, index that table to obtain the pointer to the function and then call. The extra cost compared with a direct non-polymorphic call is just the table lookup. (In fact there can be other hidden costs when using multiple inheritance, as the implicit this pointer might have to be shifted), but the cost of the virtual dispatch is very small.
I don't know the first thing about Objective-C, but here's why you want to "declare an object as one class and instantiate it as another": the Liskov Substitution Principle.
Since a PDF is a document, and an OpenOffice.org document is a document, and a Word Document is a document, it's quite natural to write
Document *d;
if (ends_with(filename, ".pdf"))
d = new PdfDocument(filename);
else if (ends_with(filename, ".doc"))
d = new WordDocument(filename);
else
// you get the point
d->print();
Now, for this to work, print would have to be virtual, or be implemented using virtual functions, or be implemented using a crude hack that reinvents the virtual wheel. The program need to know at runtime which of various print methods to apply.
Templating solves a different problem, where you determine at compile time which of the various containers you're going to use (for example) when you want to store a bunch of elements. If you operate on those containers with template functions, then you don't need to rewrite them when you switch containers, or add another container to your program.
A virtual function is important in inheritance. Think of an example where you have a CMonster class and then a CRaidBoss and CBoss class that inherit from CMonster.
Both need to be drawn. A CMonster has a Draw() function, but the way a CRaidBoss and a CBoss are drawn is different. Thus, the implementation is left to them by utilizing the virtual function Draw.
Well, the idea is simply to allow the compiler to perform checks for you.
It's like a lot of features : ways to hide what you don't want to have to do yourself. That's abstraction.
Inheritance, interfaces, etc. allow you to provide an interface to the compiler for the implementation code to match.
If you didn't have the virtual function mecanism, you would have to write :
class A
{
void do_something();
};
class B : public A
{
void do_something(); // this one "hide" the A::do_something(), it replace it.
};
void DoSomething( A* object )
{
// calling object->do_something will ALWAYS call A::do_something()
// that's not what you want if object is B...
// so we have to check manually:
B* b_object = dynamic_cast<B*>( object );
if( b_object != NULL ) // ok it's a b object, call B::do_something();
{
b_object->do_something()
}
else
{
object->do_something(); // that's a A, call A::do_something();
}
}
Here there are several problems :
you have to write this for each function redefined in a class hierarchy.
you have one additional if for each child class.
you have to touch this function again each time you add a definition to the whole hierarcy.
it's visible code, you can get it wrong easily, each time
So, marking functions virtual does this correctly in an implicit way, rerouting automatically, in a dynamic way, the function call to the correct implementation, depending on the final type of the object.
You dont' have to write any logic so you can't get errors in this code and have an additional thing to worry about.
It's the kind of thing you don't want to bother with as it can be done by the compiler/runtime.
The use of templates is also technically known as polymorphism from theorists. Yep, both are valid approach to the problem. The implementation technics employed will explain better or worse performance for them.
For example, Java implements templates, but through template erasure. This means that it is only apparently using templates, under the surface is plain old polymorphism.
C++ has very powerful templates. The use of templates makes code quicker, though each use of a template instantiates it for the given type. This means that, if you use an std::vector for ints, doubles and strings, you'll have three different vector classes: this means that the size of the executable will suffer.