What is the difference between compile-time polymorphism and static binding?

Did this link help me understand the difference between static snapping and dynamic snapping? but I'm confused that

What is the difference between static binding and compile-time polymorphism, or is there no difference. .

Does it also raise doubts about dynamic binding and runtime polymorphism?

+7
c ++ binding
source share
5 answers

In short

Static and dynamic bindings about when the exact code to run is known (that is, the address of the function): when compiling, link (both "static"), and when loading or starting (both "dynamic").

Polymorphism, firstly, about how a well-known code is known: in order to qualify as polymorphism, it is necessarily inferred from the type of data being processed. When the “dynamic type” of data is not known before runtime (often because the type is determined by the input of the runtime data), dynamic binding must be used, and this requires dynamic polymorphism (similar to polymorphism at runtime, C ++ offers virtual dispatch mechanism in this category). There are other situations where virtual dispatching is useful even though the types of processed data are available at compile time, especially to minimize / eliminate (re) compilation time after changing the code, as well as to configure the "bloat" code. In any case, compilation time or static polymorphism uses what is known about types at compile time to bind at compile time or bind time (ie, "Statically").

Examples

struct Base { virtual void f(); void g(); }; struct Derived : Base { void f(); void g(); }; Derived d; df(); // if definition in a shared library, needs dynamic binding // otherwise (same translation unit, linked object, static lib) // compiler should optimise to static binding // (though functionally either would work) Base* p = factory(data); p->f(); // dynamic binding - if p points to a Base, use Base::f() // - if p pointer to a Derived, use Derived::f() void some_func(const char*); // note: no polymorphism / overloads some_func("hello world\n"); // if some_func is defined in... // - shared / dynamic link library, binds dynamically // - otherwise, static binding std::cout << "hello world\n"; // static binding // compile-time polymorphism from (operator) overloading 

Discussion

the binding usually refers to the time when the program allows the function to be called for a specific machine code for the implementation of the function:

  • static means this happens at compile time

  • dynamic means that this happens when the executable is running / running

"binding" - and "currying" - are also used to describe the conditions of arguments to functors (search for "bindings" in Stroustrup C ++ 11 Frequently Asked Questions )

The only situations in which C ++ programs associate function calls dynamically are:

  • when a dynamic library is used, in which case the binding can be performed by the operating system loader before calling main() or explicitly in the code using dlsym (or a similar function specific to the OS) which returns a pointer to a function to call the function found in the dynamic library ( .so, .dll, ...).

  • in virtual dispatch, when a virtual member function is found at run time, usually following the pointer from the data object to the virtual dispatch table where the function pointer is written

  • when function pointers are explicitly used by the programmer

In other situations, the binding is static: the compiler writes jmp or a call to a specific address / memory offset (regardless of whether it is absolute or relative to the program counter) in the object or executable file that it creates and that does not change when loading or program execution.

The classification of static / dynamic binding has only a slight coincidence with polymorphism:

  • virtual dispatch typically uses dynamic linking (but can sometimes be optimized according to the examples above) and

  • all other forms of polymorphism in C ++ (namely, overloading, templates, built-in macro extensions) use static binding, but

  • this is what most non-polymorphic codes do: any “normal” non-virtual function call that is not part of the shared / dynamic library is also allowed at compile time.

+8
source share

Polymorphism refers to the ability of an object to behave differently with the same message.

Polymorphism has two types. static or dynamic. In dynamic polymorphism, the response to a message is determined at run time, and in static polymorphism, it is determined at compile time.

The assignment of data types in dynamic polymorphism is called late or dynamic binding. In the process of dynamic binding, a call is made based on the type of the object (instance) at run time. For example: override method

If the assignment of data types at compile time is known as early or static binding. In the static binding method, the call is based on the reference type at compile time. For example: method overload

Method overload. This means creating a new method with the same name and a different signature. He uses early binding.

Method overriding is the process of providing a new definition of an existing method in its child class. The entire object created at runtime on the heap, so the actual binding is done only at runtime.

+4
source share

An important difference is that when an error occurs, an error is displayed. If you have static binding, you can catch an error at compile time. Runtime Error.

+2
source share

The difference is that at first it is a method (binding), and the second is a function (polymorphism), which can be used on the basis of this technique.

Polymorphism means writing common code to work with different objects without knowing their exact types.

Static binding is a language property that allows the compiler to resolve the type specified at compile time. But there can be a static binding without polymorphism.

Dynamic binding is a language property that allows you to determine the type at runtime. But there may be dynamic binding without polymorphism. If dynamic linking is used to write generic code that works with objects of several classes in a hierarchy, then this will be dynamic polymorphism.

+1
source share

The compilation time polymorphism is rather vague and controversial. Polymorphism is used to invoke a specific method based on the type of an object at runtime. It is closely associated with late binding or dynamic binding. You achieve this with the virtual :

 class Base { virtual void do() // Note the virtual { cout << "Base" << endl; } }; class Derived : public Base { virtual void do() { cout << "Derived" << endl; } }; void use(Base& b) { b.do(); // There you have late binding with 'virtual' // If you remove 'virtual', you have early binding, // Base::do() will be called everytime } Base b; Derived d; use(b); // print Base use(d); // print Derived, but print Base if you do not use virtual in Base. 

Function overloading is just syntactic sugar, not related to polymorphism. You can use it to write:

  void use(int); void use(MyClass&); void use(const std::string&); 

instead:

  void useInteger(int); void useMyClass(MyClass&); void useString(const std::string&); 

As you can use this with methods, you can assume that this is due to polymorphism. Remember that it does not mix well with polymorphism!

Regarding static polymorphism, this term was once used to describe a template used with templates that simulate polymorphism at compile time: see CRTP or Curriously Recuring Template Pattern

+1
source share

All Articles