1493266679p6m35 Etext
1493266679p6m35 Etext
Module - 35
1. Introduction
2. Pointers
3. Pointers to Objects
4. Pointers to Derived Classes
5. Polymorphism
6. Virtual functions
7. Virtual Destructor
8. Abstract class and Pure Virtual Function
9. Summary
Learning outcome –
After studying this module, you will be able to:
1. Study about Pointers
2. Learn about Pointer to Objects
3. Study about Pointers to Derived Classes
4. Polymorphism
5. Learn about Virtual Functions
6. Study about Virtual Destructor
7. Learn about Abstract class and Pure Virtual Function
1. Introduction
The memory of computer is planned as a sequential group of bytes. Every byte in the memory of
the computer has a unique address. In the same way, each and every variable in the program is
accumulated at a unique address. A pointer is a variable that holds the memory address,
generally the location of another variable in the memory. The C++ programming language
permits to have pointers to objects. The pointers that are pointing to the objects are referred to as
Object Pointers. The polymorphism is the capability of objects to take dissimilar forms. The
ability to show the behavior of the variable depending on the condition is a great ability in any
programming language. In previous units, the polymorphism concept is studies by using the
concepts of function overloading and operator overloading. C++ supports a method identified as
virtual function to accomplish run-time polymorphism.
2. Pointe rs
A pointer is a variable that tries to hold a memory address, generally the location of another
variable in memory. Pointers try to provide another approach to contact other data objects. Some
of the arithmetic operators that can be used with pointers are ++, --, +, -, += and -=. At every
instance, when a pointer is incremented by 1, then it tries to point to the memory location of the
next element of the respective base type.
Example:
Suppose, if “ptr” is a pointer of character data type, then “ptr++” will try to increment “ptr” by 1
byte, on the other hand, if “ptr” is an integer pointer, then “ptr++” will try to increment by 4
bytes.
cout<<numbers[i]<<endl;
iptr=numbers;
cout<<"Value of iptr = "<<*iptr<<endl;
iptr++;
cout<<"Value of iptr ++ "<<*iptr<<endl;
iptr--;
cout<<"Value of iptr -- "<<*iptr<<endl;
iptr=iptr+2;
cout<<"Value of iptr +2 "<<*iptr<<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Integer array values are
57
74
22
18
90
Value of iptr = 57
Value of iptr ++ 74
Value of iptr -- 57
Value of iptr +2 22
3. Pointe r to Objects
A pointer can position to objects like that of simple data types and arrays. Sometimes, there may
be a situation, that, how many objects are to be created in the program. So, the solution for such
type of situations is that, the new operator is to be used to create the objects in the program,
when the program is running, because, the new operator tries to returns a pointer to the nameless
objects. In general, it is probable for a pointer to position to a class object. It is known as object
pointer. The Object pointers are of use in creating objects at run time. It is also possible that the
public members of class can be accessible by using the object pointers.
int get_values()
{
return i;
}
};
int main()
{
first f(88), *fp;
fp = &f;
cout << "Value is "<<fp->get_values();
return 0;
}
When the above code is compiled and executed, it produces the following result:
Value is 88
fobject[i] = fobjectpointer;
}
for (i = 0; i < 10; i++)
cout << "# " << i+1 << ": " << fobject[i]->Get_Age() << endl;
for (i = 0; i < 10; i++)
{
delete fobject[i];
fobject[i] = NULL;
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
# 1: 1
# 2: 3
# 3: 5
# 4: 7
# 5: 9
# 6: 11
# 7: 13
# 8: 15
# 9: 17
# 10: 19
Example:
class base_class
{
…
};
class derived_class : public base_class
{
…
};
Then, it is possible to write:
base_class *bp1;
derived_class dobj;
bp1 = &dobj;
base_class *bp2 = new derived_class;
int main()
{
Base *bp;
Base b1;
Derived d1;
bp = &b1;
bp->seta(20);
cout << "Base class object a is " << bp->geta() << endl;
bp = &d1;
bp->seta(40);
C and C++ Programming
Electronic Science
35. Pointers, Virtual Function, Polymorphism
9
d1.setb(16);
cout << "Derived class object a is " << bp->geta() << endl;
cout << "Derived class object b is " << d1.getb() << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Base class object a is 20
Derived class object a is 40
Derived class object b is 16
5. Polymorphism
The Polymorphism is an amalgamation of two Greek words, i.e. poly and morphism. Poly means
“many” and morphism means “form”. The functionality of this aspect resemble by means of its
name. The two forms of polymorphism that is supported by C++ language are Compile-time
Polymorphism and Run-time Polymorphism.
Polymorphism
The process of Operator overloading is accomplished by permitting the operators to work on the
user defined data type with the same style as that of built- in data types. With the help of function
overloading, it is possible to write dissimilar functions by using same function name but with
dissimilar argument lists. The function would carry out different operation depending on the
parameter list in the function call. The overloaded member functions are chosen for invoking by
matching the number of arguments and kind of arguments. This information is identified to the
compiler at the compile time itself and as a result the choice of the suitable function is prepared
at the compile time only. It is must to use the scope resolution operator (::) to state the class
while invoking the functions with the objects of the derived class. But it would be good only if
the suitable member function could be chosen while the program is running. With the help of
inheritance and virtual functions, C++ determines which edition of that function to call. This is
determined at run-time and therefore, it is known as run-time polymorphism. In run-time
polymorphism, the function is related with a particular class to a large extent later on after the
compilation and as a result it is also known as late binding or dynamic binding.
6. Virtual Functions
C and C++ Programming
Electronic Science
35. Pointers, Virtual Function, Polymorphism
10
In the process of Late Binding, the function call is determined at runtime. Therefore, the
compiler decides the object’s type at runtime, and then it connects the task of function call. Late
Binding is also called as Dynamic Binding or Runtime Binding. A Virtual Function is a member
function that is declared within the base class, which is redefined or overrided in the derived
class, and which informs the compiler to carry out Late Binding on this function. When the same
function name is to be used in the base class and derived class, then the function in base class can
be declared as virtual with the help of the virtual keyword prior to the normal declaration. When
a function is declared as virtual, it helps in determining which function is to be used at run time
based on the object’s type that is pointed to by the base pointer. By making the base pointer to
spot to derived objects, it is possible to implement dissimilar versions of the virtual function. The
main advantage of virtual keyword is that it tries to verify if a member function of a class can be
over-ridden in its derived classes or not. The advantage of containing virtual function is that it is
possible to access the function that is defined in derived class by using the pointer variable of
base class. The virtual function tries to apply the “one interface, multiple methods” idea that
bring about polymorphism.
Syntax:
virtual return_type function_name()
{
…..
…..
}
Example:
virtual void display()
{
…..
…..
}
When functions are declared as virtual, the compiler tries to add a data member secretly to the
class. This data member is referred to as a virtual pointer (VPTR). A table called virtual table
(VTBL) holds pointers to all the functions that have been declared as virtual in a class, or any
other classes that are inherited. At any time, a call to a virtual function is made in the C++
program, the compiler tries to generate the code that is used to treat VPTR as the starting address
of an array of pointers to functions. The code of the function call basically indexes into this array
and calls the function that is located at the indexed addresses. The binding of function call at all
times needs these dynamic indexing activities which always take place at run-time. If a call to a
virtual function is made, while take care of the object that is defined in question, as a member of
its base class, then the accurate derived class function will be called. As a result, dynamic
binding is accomplished with the help of virtual functions.
When a function is made active through a pointer to the base class, then:
a) If the function is not defined as virtual, then, a Static Binding is performed at compilation
time. The method of the base class method gets activated.
int main()
{
Base bp;
Derived dp;
Base *bptr;
bptr=&bp;
bptr->display();
bptr=&dp;
bptr->display();
return 0;
}
When the above code is compiled and executed, it produces the following result:
Base class display
Derived class display
int main ()
{
Figure *fp;
Rectangle rt;
fp = &rt;
fp -> setvalues (5,4);
cout << "Area of rectangle is "<<fp -> area_of_figure() << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Area of rectangle is 20
int main()
{
Base *b1;
Base b2(10);
Derived1 derived1(10);
Derived2 derived2(10);
b1 = &b2;
b1->myvirtualfunction();
b1 = &derived1;
b1->myvirtualfunction();
b1 = &derived2;
b1->myvirtualfunction();
return 0;
}
When the above code is compiled and executed, it produces the following result:
Base class version of my virtual function()
10
Derived1 class version of my virtual function()
100
Base class version of my virtual function()
10
7. Virtual Destructor
The Destructor in the Base class can be Virtual. Every time, when upcasting is performed, then,
it is must that that destructor of the base class to make virtual for appropriate devastation of the
object when the program exits. In general, the constructors can never be virtual, but destructors
can be virtual.
Program to implement the usage of upcasting without virtual destructor
#include <iostream>
using namespace std;
class base1
{
public:
~base1()
{
cout << "destructing base1 "<<endl;
}
C and C++ Programming
Electronic Science
35. Pointers, Virtual Function, Polymorphism
15
};
class derived1 : public base1
{
public:
~derived1()
{
cout << "destructing derived1 "<<endl;
}
};
int main()
{
base1 *bp1 = new derived1;
delete bp1;
return 0;
}
When the above code is compiled and executed, it produces the following result:
destructing base1
destructing derived1
destructing base1
Example:
virtual void area()=0;
Program to perform addition and subtraction operations using the concept of pure virtual
function
#include<iostream>
using namespace std;
class baseclass
{
protected:
int n1;
int n2;
int result;
public:
void set(int x1, int y1)
{
n1=x1;
n2=x2;
}
virtual void operation() = 0;
int get()
{
return result;
}
};
class addition : public baseclass
{
public:
void operation()
{
result=n1+n2;
}
};
class subtraction : public baseclass
{
public:
void operation()
{
result=n1-n2;
}
};
int main()
{
int number1, number2;
baseclass *bcp;
addition aoper;
subtraction soper;
cout<<"\nEnter two numbers ";
cin>>number1>>number2;
bcp=&aoper;
bcp->set (number1,number2);
bcp->operation();
cout<<"\nResult of Addition is "<<bcp->get ();
bcp=&soper;
bcp->set (number1,number2);
bcp->operation();
cout<<"\nResult of Subtraction: "<<bcp->get ();
return 0;
}
When the above code is compiled and executed, it produces the following result:
Enter two numbers 23 10
Result of Addition is 33
C and C++ Programming
Electronic Science
35. Pointers, Virtual Function, Polymorphism
18
Result of Subtraction: 13
int main ()
{
Figure *fp;
Rectangle rt;
fp = &rt;
fp ->setvalues (8,7);
cout << "Area of Rectangle is " << fp -> area_of_figure() << endl;
Triangle tr;
fp = &tr;
fp -> setvalues (10,5);
cout << "Area of Triangle is " <<fp->area_of_figure() << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Area of Rectangle is 56
Area of Triangle is 25
9. Summary
Some of the arithmetic operators that can be used with pointers are ++, --, +, -, += and -=.
A pointer can position to objects like that of simple data types and arrays.
The pointers cannot only be used on objects of the base class, but they can also be used
on objects of derived class also.
Even though, C++ language permits a pointer of the base class to position to any object
that is derived from the base class, but the pointer ca nnot be used straightforwardly to
access all the members of the derived class.
The Polymorphism is an amalgamation of two Greek words, i.e. poly and morphism.
The two forms of polymorphism that is supported by C++ language are Compile-time
Polymorphism and Run-time Polymorphism.
In run-time polymorphism, the function is related with a particular class to a large extent
later on after the compilation and as a result it is also known as late binding or dynamic
binding.
A Virtual Function is a member function that is declared within the base class, which is
redefined or overrided in the derived class, and which informs the compiler to carry
out Late Binding on this function.
The virtual function tries to apply the “one interface, multiple methods” idea that bring
about polymorphism.
A table called virtual table (VTBL) holds pointers to all the functions that have been
declared as virtual in a class, or any other classes that are inherited.
If the function is not defined as virtual, then, a Static Binding is performed at compilation
time. The method of the base class method gets activated.
Every time, when upcasting is performed, then, it is must that that destructor of the base
class to make virtual for appropriate devastation of the object when the program exits.
Abstract Class is a class which contains as a minimum of one Pure Virtual function in it.
Abstract classes are mainly used to make available an Interface for its sub classes.
The Abstract classes are mostly used for the process of Upcasting, so that it is possible
for the derived classes to use its interface.
A pure virtual function is a function that is declared in a base class but it does not have
definition, but it is defined in the derived class.
The pure virtual function begins with virtual keyword and ends with =0.