Loading....
Coupon Accepted Successfully!

 

Binding In C++

Though C++ is an object-oriented programming language, it is very much inspired by procedural language. A program in C++ is executed sequentially line by line. Each line of the source program after translation is in the form of machine language. Each line in the machine language is assigned a unique address. Similarly, when a function call is encountered by the complier during execution, the function call is translated into machine language, and a sequential address is provided. Thus, binding refers to the process that is to be used for converting functions and variables into machine language addresses. The C++ supports two types of binding: static or early binding and dynamic or late binding.

Static (Early) Binding

In this section, we are going to focus on static or early binding. Even though similar function names are used at many places, their references and their positions are indicated explicitly by the compiler. Their ambiguities are fixed at compile time. Consider the following example.
 

class first // base class

{

int d;

public:

void display() {------} // base class member function

};

class second : public first // derived class

{

int k:

public:

void display() {-------} // member function of derived class

}


In the above program, base and derived classes have a similar member function name
display() but after conversion into machine language, addresses for two display() functions are different and unique. Thus, the compiler instructs the CPU to jump to the different addresses when similar display() function calls are executed at various places in the program. This is not an overloaded function, because its prototype is the same and it is defined in different classes.
 
The following program is based on early binding:
 

15.1 Write a program to invoke function using scope access operator.

#include<iostream.h>

#include<conio.h>

class first

{

int b;

public:

first() {b=10;}

void display() {cout<<“\n b=”<<b;}

};

class second: public first

{

int d;

public:

second() {d=20;}

void display() {cout<<“\n d=”<<d;}

};

int main()

{

clrscr();
second s;
s.first::display(); // Invokes base class function
s.display(); // Invokes derived class function
return 0;

}

OUTPUT
b = 10
d = 20

Explanation:
In the above program, the class first is a base class and class second is a derived class. Both the classes contain one integer data member and member function. The display() function is used to display the content of the data member. Both the classes contain a similar function name. In function main(), s is an object of the derived class second. Hence, in order to invoke the display() function of the base class, the scope access operator is used. When base and derived classes have similar function names, in such a situation, it is very essential to provide information to the compiler at run time about the member functions. The mechanism that provides run-time selection of a function is called a polymorphism.
 
A virtual keyword plays an important role in late binding. Before introducing virtual functions, let us have a look at the given below program. The following program shows what happens when functions are not declared virtual. This is an example of early binding.
 

15.2 Write a program to invoke member function of base and derived class using pointer of base class.

#include<iostream.h>

#include<conio.h>

class first

{ int b;

public:

first() {b=10;}

void display() {cout<<“\n b=” <<b;}

};

class second: public first

{

int d;

public:

second() {d=20;}

void display() {cout<<“\n d=”<<d;}

};

int main()

{

clrscr();

first f,*p;
second s;
p=&f;
p->display();
p=&s;
p->display();
return 0;

}

OUTPUT
b = 10
b = 10

Explanation:
In the above program, the class first is a base class and class second is a derived class. The variable f is an object of the base class, and s is an object of the derived class. The pointer *p is an object pointer of the base class. The address of the base class object is assigned to pointer p, and display() function is called. Again, the address of the derived class is assigned to pointer p, and display() function is called. Both the times, the display() function of base class is executed. This is so, because though in the second call p contains the address of the object of the derived class, yet the display() function of the base class replaces the existence of the display() function of the derived class. In order to execute various forms of the same function defined in the base, derived class, run-time binding is necessary, and it can be achieved using the virtual keyword.

Dynamic (Late) Binding

In the case of a few programs, it is impossible to know which function is to be called until run time. This is called dynamic binding. Dynamic binding of member functions in C++ can be done using the virtual keyword. The member function followed by the virtual keyword is called a virtual function. Consider the following example:
 

class first // base class

{

int d;

public:

virtual void display() {------} // base class member function

};

class second: public first // derived class

{

int k:

public:

virtual void display() {-------} // member function of derived class

}


In the example of the above program, base and derived classes have a similar member function
display() preceded by the keyword virtual. The various forms of virtual functions in base and derived classes are dynamically bound. The references are detected from the base class. All virtual functions in derived classes are considered virtual, supposing they match the base class function exactly in the number and types of parameters sent. If there is no match between these functions, they will be assumed as overloaded functions. The virtual function should be defined in the public section. If the function is declared virtual, the system will use dynamic (late) binding, which is carried out at run time. Otherwise, early or compile-time binding is used.
 
Dynamic binding can be implemented with function pointers. In this method, the pointer points to a function instead of a variable. A simple programming example is given below based on late binding.
 

15.3 Write a program to perform few arithmetic operations on floating numbers using functions. Use function pointer (Late binding).

#include<iostream.h>

#include<conio.h>

float add(float m, float n)

{

return m+n;

}

float sub(float m, float n)

{

return m-n;

}

float mul(float m, float n)

{

return m*n;

}

int main()

{

clrscr();

float x,y;

cout<<“Enter two numbers:”;

cin>>x>>y;

int task;

do

{

cout<<“Enter task (1=add, 2=sub, 3=mul):”;

cin>>task;

}

while (task< 1 || task > 3);
float (*pt)(float, float);
// Function pointer named pt is created
switch (task)
{
case 1:
pt=add;
break;
case 2:
pt=sub;
break;
case 3:
pt=mul;
break;
}
cout<<“Result of operation is:” << pt(x,y) << endl;
return 0;

}

OUTPUT
Enter two numbers: 2.5 2.5
Enter task (1=add, 2=sub, 3=mul): 3
Result of operation is : 6.25

 


Explanation:
In the above program, instead of calling functions directly, we have called them through function pointer pt. The complier is unable to use static or early binding in this case. In this program, the late binding concept is implemented. The compiler has to read the addresses held in the pointers toward different functions. Until run time, decisions are not taken as to which function needs to be executed; hence, it is late binding.




Test Your Skills Now!
Take a Quiz now
Reviewer Name