chapter4_Pointers and Polymorphism in C++

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 19

CHAPTER 4

POINTER AND POLYMORPHISM IN C++

POINTER AND ITS DECLARATION


A pointer is a variable that contains the memory location of another variable. In C++ a pointer is a
variable that points to or references a memory location in which data is stored. Each memory cell in the
computer has an address that can be used to access that location so a pointer variable points to a memory
location we can access and change the contents of this memory location via the pointer.
Programmer start by specifying the type of data stored in the location identified by the pointer. The
asterisk(*) tells the compiler that you are creating a pointer variable. Finally programmer give the name
of the variable.

Syntax:
data_type *pointer_variable_name;

Example:
int *ptr;
float *ptr1;

TWO POINTER OPERATOR


Following are pointer operator:
1. & (address of operator)
2. * (Value of operator)

USE OF ADDRESS OPERATOR


Once we declare a pointer variable we must point it to something. We can do this by assigning to the
pointer the address of the variable you want to point as in the following example:
Ptr = #
This places the address where num is stores into the variable ptr. If num is stored in memory 21260
address then the variable ptr has the value 21260.

#include<iostream.h>
#include<conio.h>
void main()
{
int *ptr;
int sum=45;
clrscr();
ptr=&sum;
cout<<"\n the value is:"<< sum;
cout<<"\n The value is:"<<ptr;
cout<<"\n The value is:"<<*ptr;
getch();
}
Output
the value is:45
The value is:0x8f98fff4
The value is:45

POINTER ARITHMETIC
C++ allows pointers to perform the following arithmetic operations:
1 A pointer can be incremented (++) or decremented (--)
2 Any integer can be added to or subtracted from a pointer.
3 One pointer can be subtracted from another.
Example:
int a[6];
int *ptr;
ptr=&a[0];
ptr refers to the address of the variable a.
ptr++ or ++ptr
This statement moves the pointer to the next memory address .Similarly we can decrement the pointer
variable as follows:
Ptr-- or --ptr-
This statement moves the pointer to the previous memory address. Also, if two pointer variables points to
the same array can be subtracted from each other.

Program:
#include<iostream.h>
#include<conio.h>
void main( )
{
int num[5]={56,75,22,18,90};
int *ptr, i;
double j;
clrscr();
ptr=&num[0];
int *ptr1=&num[2];
cout<<"value of ptr:"<<*ptr<<endl;
ptr++;
cout<<"value of ptr++:"<<*ptr<<endl;
ptr--;
cout<<"value of ptr--:"<<*ptr<<endl;
ptr=ptr+2;
cout<<"value of ptr+2:"<<*ptr<<endl;
ptr=ptr-1;
cout<<"value of ptr-1:"<<*ptr<<endl;
ptr=ptr+3;
cout<<"value of ptr+=3:"<<*ptr<<endl;
j=ptr-ptr1;
cout<<"value of j:"<<j<<endl;
getch();
}
Output
value of ptr:56
value of ptr++:75
value of ptr--:56
value of ptr+2:22
value of ptr-1:75
value of ptr+=3:90
value of j:2

POINTER TO OBJECT
When address of an object of a class is stored into the pointer variable of the same class type then it is
pointer to object.
Declaration and Use of Object Pointers
Just like other pointers, the object pointers are declared by placing * in front of a object pointer's name. It

class-name ∗object-pointer;
takes the following general form:
where class-name is the name of an already defined class and object-pointer is the pointer to an object of
this class type.
Example:
item x,*ptr;
ptr=&x;
When accessing members of a class using an object pointer, the arrow operator (->) is used instead of dot
operator.
ptràgetdata(100,75.75);
ptràshow();
since, (*ptr) is an alias of ‘x’ , we can also use the following method:
(*ptr).show();
The paranthesis are necessary because, the dot operator has the higher precedence than the indirectional
operator(*).

Program:
#include<conio.h>
#include<iostream.h>
class product
{
private:
int code;
float price;
public:
void getdata(void)
{
cout<<"\n Enter code";
cin>>code;
cout<<"\n Enter price";
cin>>price;
}
void display(void)
{
cout<<"\nCode="<<code<<"\n
Price="<<price;
}
};
void main()
{
product p1; //create object of product
product *ptr; //create pointer of type product
ptr=&p1; //ptr points to object p 1
ptr->getdata (); // Invoking getdata()using pointer to object
p1.display(); // Invoking putdata()using object
}

EXP 14_01 Write a C++ program to declare a class "Book" containing data members
book_name,author_name and price. Accept this information for one object of the class using pointer to
that object
#include<iostream.h>
#include<conio.h>
#include<string.h>
class Book
{
private:
char book_name[20];
char author[20];
float price;
public:
void accept()
{
cout<<"enter details of book"<<endl;
cout<<"enter book name:";
cin>>book_name;
cout<<"enter author name:";
cin>>author;
cout<<"enter price:";
cin>>price;
}
void display()
{
cout<<"book name:"<<book_name<<endl;
cout<<"author name:"<<author<<endl;
cout<<"price:"<<price;
}
};
void main()
{
Book b,*bptr;
bptr=&b;
clrscr();
bptr->accept();
bptr->display();
getch();
}
Output
enter details of book
enter book name:C++
enter author name:balagurusamy
enter price:453
book name:C++
author name:balagurusamy
price:453

EXP14_02 Write a C++ program to declare a class "Box" having data members
height,width and breadth. Accept this information for one object using
pointer to that object. Display this area and volume of that object
#include<iostream.h>
#include<iostream.h>
#include<conio.h>
class box
{
int a,area,volume;
public:
void getdata()
{
cout<<"\n Enter height: ";
cin>>a;
}
void calculate()
{
area=6*(a*a);
volume=(a*a*a);
}
void display()
{
cout<<"\n Area: "<<area;
cout<<"\n Volume: "<<volume;
}
};
void main()
{
clrscr();
box b,*ptr;
ptr=&b;
ptr->getdata();
(*ptr).calculate();
ptr->display();
getch();
}
Enter height: 2
Area: 24
Volume: 8

THIS POINTER
C++ uses a unique keyword called “this” to represent an object that invokes a member function.
The starting address is same as the address of the first variable in the class structure.
This unique pointer is automatically passed to a member function when it is called.
the pointer ‘this‘ acts as an implicit argument to all the member functions.
Its an in-built pointer so programmer doesn’t need to explicitly create this pointer.
One class can have exactly one this pointer.
For example, the function call A.max () will set the pointer “this” to the address of the object A. Next
time suppose we call B.max(), the pointer “this” will store address of object B.

Program:
#include<conio.h>
#include<iostream.h>
class sample
{
int a;
public:
void getdata()
{
cout<<"enter the value of a:";
cin>>a;
}
void putdata()
{
cout<<"the value of a is:"<<this ->a;
}
};
void main()
{
clrscr();
sample s;
s.getdata();
s.putdata();
getch();
}
Output
enter the value of a:123
the value of a is:123

POINTER TO DERIVED CLASS


We can use pointer to not only to the base object but also to the object of the derived class.
Pointers to object of a base class are type compatible with pointers to objects of a derived class.
Therefore, a single pointer variable can be made to point to objects belonging to different classes.
For example:
if ‘b’ is the base class & ‘d’ is the derived class from ‘b’ , then the pointer declared as a pointer to ‘B’ is
also a pointer to ‘D’.
B b; //base object
B *bptr; //ptr to class ‘B’ type variable.
D d; //derived object
bptr=&b; //bptr points to object ‘b’.
bptr=&d; //bptr points to object ‘d’

Program:
#include<iostream.h>
#include<conio.h>
class base
{
public:
void display()
{
cout<<"\n Base class display";
}
};
class derive : public base
{
public:
void display()
{
cout<<"\n drive class display";
}
};
void main()
{
clrscr();
base b;
base *baseptr;
cout<<"\n baseptr points to base";
baseptr=&b;
baseptr->display();
cout<<"\n baseptr points to derive";
derive d;
baseptr=&d;
baseptr->display();
getch();
}
Output
baseptr points to base
Base class display
baseptr points to derive
Base class display
POLYMORPHISM
Polymorphism is another important OOP concept.
Polymorphism, a Greek term, means the ability to take more than one form.
Polymorphism gives different meanings to the operators or functions.
A single function usage or an operator functioning in many ways can be called polymorphism
An operator may exhibit different behavior is different instances. The behavior depends upon the types of
data used in the operator. For example, consider the operation of addition. For two numbers, the
operation will generate a sum. If the operands are strings, then the operation would produce a third string
by concatenation. The process of making an operator to exhibit different behaviors in different instances
is known as operator overloading.
Fig. below illustrates that a single function name can be used to handle different number and different
types of argument. This is something similar to a particular word having several different meanings
depending upon the context. Using a single function name to perform different type of task is known as
function overloading.

TYPES OF POLYMORPHISM
C++ provides two different types of polymorphism.
1. Compile-time polymorphism
2. Run-time polymorphism

COMPILE-TIME POLYMORPHISM

The compiler is able to select the appropriate function for a particular call at compile-time itself. This is
known as compile-time polymorphism.
Compile time polymorphism refers to the binding of functions on the basis of their signature (number,
type and sequence of parameters).
It is also called early binding or static binding.
The compile-time polymorphism is implemented with templates.

1. Function overloading
2. Operator overloading
FUNCTION OVERLOADING

Using a single function name to perform different types of tasks is known as function overloading.
Using the concept of function overloading, we can design a family of functions with one function name
but with different argument lists.
The function would perform different operations depending on the argument list in the function call.
The correct function to be invoked is determined by checking the number and type of the arguments but
not on the function type.

Program using function overloading to add 2 integer numbers & three integer numbers.
#include<iostream.h>
#include<conio.h>
class Addition
{
public:
void sum(int a, int b)
{
cout<<a+b;
}
void sum(int a, int b, int c)
{
cout<<a+b+c;
}
};
void main()
{
clrscr();
Addition obj;
obj.sum(10, 20);
cout<<endl;
obj.sum(10, 20, 30);
}
/*Output
30
60
*/
EXP 18_01 Write a C++ program to find the area of various geometrical shapes by function overloading
#include<iostream.h>
#include<conio.h>
class area_calculate
{
private:
double a_c;
double a_r;
double a_t;
public:
void area(int r)
{
a_c=3.14*r*r;
cout<<"area of circle:"<<a_c<<endl;
}
void area(int l, int b)
{
a_r=l*b;
cout<<"area of rectangle:"<<a_r<<endl;
}
void area(double b,double h)
{
a_t=(0.5*(b*h));
cout<<"area of triangle:"<<a_t<<endl;
}
};
void main()
{
area_calculate a;
clrscr();
a.area(2);
a.area(2,3);
a.area(2.0,3.0);
getch();
}
/*Output
area of circle:12.56
area of rectangle:6
area of triangle:3
*/

Exp 18_2 Write a C++ program to interchange the values of two int,float and char using function
overloading*/
#include<iostream.h>
#include<conio.h>
class swapping
{
private:
int p,q;
double a,b;
char m,n;
public:
void swap(int p1, int q1)
{
p=p1;
q=q1;
cout<<"\n***before swap:***"<<endl;
cout<<"first integer number:"<<p<<endl;
cout<<"second integer number:"<<q<<endl;
int temp;
temp=p;
p=q;
q=temp;
cout<<"\n***after swap:***"<<endl;
cout<<"first integer number:"<<p<<endl;
cout<<"second integer number:"<<q<<endl;
}
void swap(double a1, double b1)
{
a=a1;
b=b1;
cout<<"\n***before swap:***"<<endl;
cout<<"first float number:"<<a<<endl;
cout<<"second float number:"<<b<<endl;
double temp;
temp=a;
a=b;
b=temp;
cout<<"\n***after swap:***"<<endl;
cout<<"first float number:"<<a<<endl;
cout<<"second float number:"<<b<<endl;
}
void swap(char m1, char n1)
{
m=m1;
n=n1;
cout<<"\n***before swap:***"<<endl;
cout<<"first char:"<<m<<endl;
cout<<"second char:"<<n<<endl;
char temp;
temp=m;
m=n;
n=temp;
cout<<"\n***after swap:***"<<endl;
cout<<"first char:"<<m<<endl;
cout<<"second char:"<<n<<endl;
}
};
void main()
{
swapping s;
clrscr();
s.swap(6,8);
s.swap(62.32,88.45);
s.swap('x','y');
getch();
}
Output
***before swap:***
first integer number:6
second integer number:8
***after swap:***
first integer number:8
second integer number:6
***before swap:***
first float number:62.32
second float number:88.45
***after swap:***
first float number:88.45
second float number:62.32
***before swap:***
first char:x
second char:y
***after swap:***
first char:y
second char:x
OPERATOR OVERLOADING

The process of making an operator to exhibit different behaviors in different instances is known as
operator overloading.
Operator function - Defines the new task which is going to be assigned to the operator.
Syntax:
returntype classname :: operator op(arglist)
{
function body //task defined
}
Example:
void space::operator-()
{
x = -x;
y = -y;
z = -z;
}

Operator overloading can be achieved using


i) member function
ii) friend function
We can overload both unary and binary operator

UNARY OPERATOR OVERLOADING


Unary operator requires
i) no arguments when overloaded with member function
ii) one arguments when overloaded with friend function

Exp 16_02 Write a C++ program to overload unary operator (++)increment


and (--)decrement
#include<iostream.h>
#include<conio.h>
class op_ov
{
int num;
public:
void getdata()
{
cout<<"enter number:";
cin>>num;
}
void operator++()
{
num=num+1;
cout<<"number after increment is:"<<num<<endl;
}
void operator--()
{
num=num-1;
cout<<"number after decrement is:"<<num<<endl;
}
};
void main()
{
op_ov o;
clrscr();
o.getdata();
++o;
o.getdata();
--o;
getch();
}
/*OUTPUT
enter number:50
number after increment is:51
enter number:80
number after decrement is:79
*/

EXP 16_03 Write a C++ program to overload unary '-' operator to negate values using member
function
#include<iostream.h>
#include<conio.h>
class negate
{
int a,b,c;
public:
void getdata()
{
cout<<"Enter the values:"<<endl;
cout<<"a= ";
cin>>a;
cout<<"b= ";
cin>>b;
cout<<"c= ";
cin>>c;
}
void putdata()
{
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
cout<<"c= "<<c<<endl;
}
void operator-()
{
a=-a;
b=-b;
c=-c;

}
};
void main()
{
clrscr();
negate n;
n.getdata();
cout<<"\nbefore negation:"<<endl;
n.putdata();
-n;
cout<<"\nafter negation:"<<endl;
n.putdata();
getch();
}
/*Output
Enter the values:
a= 4
b= -5
c= 6
before negation:
a= 4
b= -5
c= 6
after negation:
a= -4
b= 5
c= -6*/

BINARY OPERATOR OVERLOADING


Binary operator requires
i) one arguments when overloaded with member function
ii) two arguments when overloaded with friend function

EXP 17_01 Write a C++ program to add two complex numbers using operator overloaded by a friend
function
#include<iostream.h>
#include<conio.h>
class complex
{
private:
float real,imag;
public:
void getdata(float r,float i)
{
real=r;
imag=i;
}
void putdata()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
complex friend operator+(complex,complex);
};
complex operator+(complex c1,complex c2)
{
complex c3;
c3.real=c1.real+c2.real;
c3.imag=c1.imag+c2.imag;
return c3;
}
void main()
{
complex com1,com2,com3;
clrscr();
com1.getdata(2.2,3.3);
cout<<"first complex number:"<<endl;
com1.putdata();
com2.getdata(4.4,5.5);
cout<<"second complex number:"<<endl;
com2.putdata();
com3=com1+com2;
cout<<"addition of two complex number is:"<<endl;
com3.putdata();
getch();
}
/*Output
first complex number:
2.2+3.3i
second complex number:
4.4+5.5i
addition of two complex number is:
6.6+8.8i
*/
EXP 17_02 Write a C++ program to compare two strings using '==‘ operator overloading
#include<iostream.h>
#include<conio.h>
#include<string.h>
class str_cmp
{
private:
char str[20];
public:
void getdata()
{
cout<<"enter string:"<<endl;
cin>>str;
}
void operator==(str_cmp s3)
{
if(strcmp(str,s3.str)==0)
cout<<"string are same"<<endl;
else
cout<<"string are not same"<<endl;
}
};
void main()
{
str_cmp s1,s2;
clrscr();
s1.getdata();
s2.getdata();
s1==s2;
getch();
}
/*Output
enter string:
MANGO
enter string:
MANGO
string are same

enter string:
APPLE
enter string:
APLE
string are not same
*/

RULES FOR OPERATOR OVERLOADING

1. Only existing operators can be overloaded. New operators cannot be created.


2. The overloaded operator must have atleast one operand that is of user-defined type.
3. We cannot change the basic meaning of an operator. That is to say, we cannot redefine the plus(+)
operator to subtract one value from the other.
4. Overloaded operators follows the syntax rules of the original operators. They cannot be overridden.
5. There are operators that cannot be overloaded.
Sizeof Sizeof Operator
. Membership operator
.* Pointer-to-member operator
:: Scope resolution operator
?: Conditional operator
6. We cannot use friend functions to overload certain operators.
= Assignment operator
( ) Function call operator

[] Subscripting operator
- > Class member access operator

7. Unary operators overloaded by means of a member function, take no explicit arguments and return no
explicit values, but those overloaded by means of friend function, take one reference argument(the
object of the relevant class).
8. Binary operators overloaded through a member function take one explicit arguments and those which are
overloaded thorough a friend function take two explicit arguments.
9. When using binary operators overloaded through a member function, the left hand operand must be an
object of the relevant class.
10. Binary arithmetic operators such as +,-,*, and / must explicitly return a value. They must not attempt to
change their own arguments

RUN-TIME POLYMORPHISM

The appropriate member function could be selected while the programming is running. This is known as
run-time polymorphism.
The run-time polymorphism is implemented with pointer to derived class and virtual functions.

VIRTUAL FUNCTIONS

An essential requirement of polymorphism is ability to refer to object without any regard of their
classes.
This requires use of single pointer variable to refer to objects of different classes.
Virtual function is a mechanism in Object oriented programming which allows the programmer to have more than
one class to have a function with same name, return type and arguments i.e. their function signature can be same.
Here we use pointer to base class to refer to all derived objects. Base pointer even when it is made to
contain address of derived class, always executes function in base class.
Compiler simply ignores content of pointer & chooses member function that matches type of pointer. In
this case polymorphism is achieved by using virtual functions.
When we use same function name in both base & derived classes, function in base class is declared as
virtual using keyword virtual preceding its normal declaration.
When function is made virtual C++ determines which function to call at run time based on type of object
pointed to by base pointer rather than type of pointer.
Thus by making base pointer to point to different objects different version of virtual function can be
executed.
Runtime polymorphism is achieved only when virtual function accessed through pointer to base class.

PROGRAM FOR VIRTUAL FUNCTION


#include<iostream.h>
#include<conio.h>
class base
{
public:
void display()
{
cout<<”Display Base”;
}
virtual void show()
{
cout<<”Show Base”;
}
};
class derived: public base
{
public:
void display()
{
cout<<”Display Derived”;
}
void show()
{
cout<<”Show Derived”;
}
};
void main()
{
base b1;
derived d1;
base *bptr;
bptr=&b1;
bptr->display();
bptr->show();
bptr=&d1;
bptr->display();
bptr->show();
getch();
}
/*Output
Display Base
Show Base
Display Base
Show Derived
*/

EXP15_01 Write a C++ program to declare a class "polygon" having data members width and height.
Derive classes "rectangle" and "triangle" from "polygon“ having area() as a member function. Calculate
area of triangle and rectangle using pointer to derived class object*/
#include<iostream.h>
#include<conio.h>
class polygon
{
public:
float width,height;
public:
void get()
{
cout<<"enter width of polygon:";
cin>>width;
cout<<"enter height of polygon:";
cin>>height;
}
virtual void area()
{
}
};
class rectangle:public polygon
{
private:
float ar_rect;
public:
void area()
{
ar_rect=width*height;
}
void display()
{
cout<<"area of rectangle is:"<<ar_rect<<endl;
}
};
class triangle:public polygon
{
private:
float ar_tr;
public:
void area()
{
ar_tr=(0.5*(width*height));
}
void display()
{
cout<<"area of triangle is:"<<ar_tr<<endl;
}
};
void main()
{
polygon p,*pptr;
rectangle r,*rptr;
triangle t,*tptr;
clrscr();
pptr=&r;
pptr->get();
pptr->area();
rptr=&r;
rptr->display();
pptr=&t;
pptr->get();
pptr->area();
tptr=&t;
tptr->display();
getch();
}
/*Output
enter width of polygon:4
enter height of polygon:5
area of rectangle is:20
enter width of polygon:6
enter height of polygon:7
area of triangle is:21
*/

RULES FOR VIRTUAL FUNCTION


1. The virtual functions must be members of some class.
2. They cannot be static members.
3. They are accessed by using object pointers.
4. A virtual function can be friend of another class.
5. A virtual function in a base class must be defined, even though it may not be used
6. The prototype of the base class version of a virtual function and all the derived class versions must
be identical. If two functions with the same name have different prototypes++considers them as
overloaded functions, and the virtual function mechanism is ignored.
7. We cannot have virtual constructors, but we can have virtual destructors.
8. While a base pointer can point to any type of the derived object, the reverse is not true. That is to
say, we cannot use a pointer to derived class to access an object of the base type.
9. When a base pointer points to a derived class, incrementing or decrementing it will not make it to
point to the next object of the derived class. It is incremented or decremented only relative to its
base type. Therefore, we should not use this method to move the pointer to the next object.
10.If a virtual function is defined in the base class, it need not be necessarily redefined in the
derived class. In such cases, calls will invoke the base function.

PURE VIRTUAL FUNCTION


A pure virtual function is a function declared in a base class that has no definition relative to the base
class.
Example: virtual void display() =0;

COMPILE TIME POLYMORPHISM VS RUNTIME POLYMORPHISM


Compile time Polymorphism Run time Polymorphism
It means that an object is bound to its function It means that selection of appropriate function is
call at compile time i.e. linking of function call done at runtime i.e. linking of function call to its
to its definition at compile time. definition at run time.
Functions to be called are known well before Function to be called is unknown until
appropriate selection is made.
This does not require use of pointers to objects This requires use of pointers to object
Function calls are faster Function calls execution are slower
It is also referred as early binding or static It is also referred as late binding or dynamic
binding. binding.
e.g. overloaded function call e.g. virtual function
It is implemented by function overloading It is implemented by virtual functions.
or operator overloading

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy