Skip to main content

Early Binding vs Late Binding in C++


BINDING IN C++
Binding refers to the process that is used to convert identifiers (such as variable and function names) into machine language addresses. Although binding is used for both variables and functions, in this lesson we’re going to focus on function binding.

Early binding
Most of the function calls the compiler encounters will be direct function calls. A direct function call is a statement that directly calls a function. For example:












#include <iostream>

void PrintValue(int nValue)
{
    std::cout << nValue;
}

int main()
{
    PrintValue(5); // This is a direct function call
    return 0;
}
Direct function calls can be resolved using a process known as early binding. Early binding (also called static binding) means the compiler is able to directly associate the identifier name (such as a function or variable name) with a machine address. Remember that all functions have a unique machine address. So when the compiler encounters a function call, it replaces the function call with a machine language instruction that tells the CPU to jump to the address of the function.
Let’s take a look at a simple calculator program that uses early binding:














































#include <iostream>
using namespace std;

int Add(int nX, int nY)
{
    return nX + nY;
}

int Subtract(int nX, int nY)
{
    return nX - nY;
}

int Multiply(int nX, int nY)
{
    return nX * nY;
}

int main()
{
    int nX;
    cout << "Enter a number: ";
    cin >> nX;

    int nY;
    cout << "Enter another number: ";
    cin >> nY;

    int nOperation;
    do
    {
        cout << "Enter an operation (0=add, 1=subtract, 2=multiply): ";
        cin >> nOperation;
    } while (nOperation < 0 || nOperation > 2);

    int nResult = 0;
    switch (nOperation)
    {
        case 0: nResult = Add(nX, nY); break;
        case 1: nResult = Subtract(nX, nY); break;
        case 2: nResult = Multiply(nX, nY); break;
    }

    cout << "The answer is: " << nResult << endl;

    return 0;
}
Because Add(), Subtract(), and Multiply() are all direct function calls, the compiler will use early binding to resolve the Add(), Subtract(), and Multiply() function calls. The compiler will replace the Add() function call with an instruction that tells the CPU to jump to the address of the Add() function. The same holds true for for Subtract() and Multiply().

Late Binding
In some programs, it is not possible to know which function will be called until runtime (when the program is run). This is known as late binding (or dynamic binding). In C++, one way to get late binding is to use function pointers. To review function pointers briefly, a function pointer is a type of pointer that points to a function instead of a variable. The function that a function pointer points to can be called by using the function call operator (()) on the pointer.
For example, the following code calls the Add() function:













int Add(int nX, int nY)
{
    return nX + nY;
}

int main()
{
    // Create a function pointer and make it point to the Add function
    int (*pFcn)(int, int) = Add;
    cout << pFcn(5, 3) << endl; // add 5 + 3

    return 0;
}
Calling a function via a function pointer is also known as an indirect function call. The following calculator program is functionally identical to the calculator example above, except it uses a function pointer instead of a direct function call:



















































#include <iostream>
using namespace std;

int Add(int nX, int nY)
{
    return nX + nY;
}

int Subtract(int nX, int nY)
{
    return nX - nY;
}

int Multiply(int nX, int nY)
{
    return nX * nY;
}

int main()
{
    int nX;
    cout << "Enter a number: ";
    cin >> nX;

    int nY;
    cout << "Enter another number: ";
    cin >> nY;

    int nOperation;
    do
    {
        cout << "Enter an operation (0=add, 1=subtract, 2=multiply): ";
        cin >> nOperation;
    } while (nOperation < 0 || nOperation > 2);

    // Create a function pointer named pFcn (yes, the syntax is ugly)
    int (*pFcn)(int, int);

    // Set pFcn to point to the function the user chose
    switch (nOperation)
    {
        case 0: pFcn = Add; break;
        case 1: pFcn = Subtract; break;
        case 2: pFcn = Multiply; break;
    }

    // Call the function that pFcn is pointing to with nX and nY as parameters
    cout << "The answer is: " << pFcn(nX, nY) << endl;

    return 0;
}
In this example, instead of calling the Add(), Subtract(), or Multiply() function directly, we’ve instead set pFcn to point at the function we wish to call. Then we call the function through the pointer. The compiler is unable to use early binding to resolve the function call pFcn(nX, nY) because it cannot tell which function pFcn will be pointing to at compile time!
Late binding is slightly less efficient since it involves an extra level of indirection. With early binding, the compiler can tell the CPU to jump directly to the function’s address. With late binding, the program has to read the address held in the pointer and then jump to that address. This involves one extra step, making it slightly slower. However, the advantage of late binding is that it is more flexible than early binding, because decisions about what function to call do not need to be made until run time.

Comments

Popular posts from this blog

Use Case Diagram for Online Book Store

Occurrences of each letter of alphabet in the text

Program to print a table indicating the no. of occurrences of each letter of alphabet in the text entered as command line arguments. #include<iostream> #include<string> using namespace std; int main(int argc, char *argv[]) { string str=""; static int alphabet[26]; int x; cout<<"\n\n Command-Line Argument\n"; for(int i=0;i<argc;i++) { cout<<"\n "<<argv[i]; str+=argv[i]; } for(int i=0;i<str.length();i++) { if(str[i]>='A' && str[i]<='Z') { x=((int)str[i])-65; alphabet[x]++; } else if(str[i]>='a' && str[i]<='z') { x=((int)str[i])-97; alphabet[x]++; } } //Displaying No. of occurrences of each alphabets in the command line argument cout<<"\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n Alphabet No. of Occurrences\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; for(int i=0;i<26;i++)...

Linear search & Binary search using Template

Write a program to search an element from a list. Give user the option to perform Linear or Binary search. Use Template functions. #include<iostream> using namespace std; template <class T> void Lsearch(T *a, T item, int n) { int z=0; for(int i=0;i<n;i++) { if(a[i]== item) { z=1; cout<<"\n Item found at position = "<<i+1<<"\n\n"; } else if(z!=1) { z=0; } } if(z==0) cout<<"\n Item not found in the list\n\n"; } template <class T> void Bsearch(T *a, T item, int n) { int beg=0,end=n-1; int mid=beg+end/2; while((a[mid]!=item) && (n>0)) { if(item>a[mid]) beg=mid; else end=mid; mid=(beg+end)/2; n--; } if(a[mid]==item) cout<<"\n Item found at position = "<<mid+1<<"\n\n"; else cout<<"\n Item not found in the list\n\n"; } void main() { int iarr[10] = {2,42,56,86,87,99,323,546,767,886};...