What is the difference between dynamic dispatch and late binding in C++?
Asked Answered
A

11

90

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.

Amarillo answered 25/11, 2013 at 8:15 Comment(1)
It's a good question and can be better if you mention links you've read.Prendergast
H
78

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.

Hessian answered 25/11, 2013 at 8:28 Comment(9)
I've tried my best to upvote this answer, that actually explains the difference. Too bad, the OP was blinded by 131k rep - and selected the worst possible answer...Pelagi
@Pelagi its all good. I generally dump any answers I post with no up-votes after a week or so because if no one finds them helpful I don't want them sticking around cluttering up the "accepted" answers. But I'm glad someone found the difference explanation here worth-while, so I'll likely just keep it now. Thanks for the support.Hessian
Dynamic dispatch is just a particular instance of late binding, where the method selector is the name, and the target method is the one to be resolved. Dynamic dispatch is basically a partially evaluated late binding.Guppy
In your example Visual Basic and C++ aren't different at all because the Obj is derived from or implements IDispatch. In C++ terms IDispatch or IUnknown is a base class, and C++ can call an unknown method name using that interface. It can also call DLL methods via LoadLibrary, GetProcAddress. But I suppose that those aren't language features.Photoconduction
@ZanLynx they're different. In VB the langauge knows nothing about that object (or that it is even a valid object at all) other than you (the program) wanting to fire a method called DoSomthing. Don't confuse the language with the runtime. I tried to make that clear, but honestly I myself am only marginally satisfied with the description. On the C++ side you would have to code the all the dynamics yourself via IDispatch, and even then, the language knows something of the object (it supports IDispatch etc.).Hessian
Would I be correct to assume that Java only has dynamic dispatch, as the class of the Object is always known in the sense that, and I quote (not necessarily the end of the inheritance hierarchy, but at least a formal base class or interface). If not what would be an example of polymorphism?Stagy
Can using typeid in C++ like this: std::cout << typeid(*ptr).name() << std::endl; be thought as late binding?Starlight
I'm not familiar with VB, but does this statement "In late binding the type of a variable is the variant at runtime" mean that late binding only applies to dynamically typed (or untyped) languages?Inheritor
regarding C++, it seems different places refer to dynamic dispatch and late binding mean the same? See Late binding in C++ on en.wikipedia.org/wiki/Late_binding > Usually, the "late binding" term is used in favor of "dynamic dispatch". Then Isocpp.org isocpp.org/wiki/faq/… says: > Dynamic binding is a result of virtual functions. --- then Wikipedia contradicts itself on en.wikipedia.org/wiki/Dynamic_dispatch >Dynamic dispatch is different from late binding (also known as dynamic binding).Oxidase
W
8

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.

Wessels answered 25/11, 2013 at 8:25 Comment(2)
Is there a link, maybe cppreference.com, where I can learn more about static and dynamic bindings?Frumpish
Are you talking about functions? Please express the terms more clearly for novices :) The answer by @Hessian and Wikipedia says there's no late binding in C++, so your answer can be confusing.Narcoma
G
8

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.

Guinness answered 25/11, 2013 at 8:32 Comment(1)
dynamic dispatch, as the name suggests, means it happens at run time. This is because the compiler doesn't have enough information.Costanzia
P
8

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.

Prendergast answered 25/11, 2013 at 8:35 Comment(0)
C
5

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

Cystolith answered 25/11, 2013 at 8:36 Comment(0)
L
4

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.

Laura answered 25/11, 2013 at 8:16 Comment(0)
T
2

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.

Tireless answered 25/11, 2013 at 8:31 Comment(0)
C
2

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.

Comedo answered 25/11, 2013 at 8:35 Comment(0)
M
2

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.

Mellar answered 25/11, 2013 at 8:36 Comment(0)
I
0

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++.

Illustrational answered 25/11, 2013 at 8:27 Comment(0)
M
0

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.

Myrmecophagous answered 25/11, 2013 at 8:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.