C++ Chapter6
C++ Chapter6
.
Polymorphism
1
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
Virtual Functions:
When we use the same functions name in both the base and derived classes, the function in base
class is declared as virtual using the key word “virtual” preceding its normal declarations.
Example
#include<iostream>
using namespace std;
class Base
{
public:
void display ()
{
cout<<"\ndisplay base:";
}
virtual void show()
{
cout <<"\nshow base\n";
}
};
class Derived: public Base
{
public:
void display ()
{
cout<<"\n\ndisplay derived:";
}
void show ()
{
cout<<"\nshow derived\n";
}
};
int main()
{
Base B;
Derived D;
Base *bptr;
cout<<"\nbptr point to base\n";
bptr = &B;
bptr->display(); //calls base version
bptr->show(); //calls base version
cout<<"\nbptr points to derived\n";
bptr = &D;
bptr->display(); // calls base version
bptr->show();//calls derived version
}
Output:
2
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
Note:
When bptr is made to point to the object ‘D’ the statement
bptr display ();
calls only the function associated with the base (i.e Base::display();), whereas the statement
bptr show ();
calls the derived version of show(). This is because the function “display ()” has not been made
virtual in the base class .
};
3
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
bptr = &D;
bptr->display();
bptr->show();
return 0;
}
4
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
“this” pointer:
C++ uses a unique keyword called “this” to represent an object that invokes a member function.
“this” is a pointer that points to the object for which “this” function was called. For example, the
function call A.max () will set the pointer “this” to the address of the object A.
Eg:
class ABC
{
int a;
………….
………….
………….
};
The private variable a can be used directly inside a member function like
a = 123;
We can also use the following statement to do the same job.
this a = 123;
Example 1
# include<iostream>
using namespace std;
class X
{
int a;
public:
void input (int a)
{
this a = a;
}
5
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
void output ()
{
cout <<a;
}
};
int main ()
{
X ob;
ob.input(2);
ob.output();
return();
}
Example 2:
# include<iostream>
using namespace std;
class X
{
int a,b;
public:
void input ()
{
this a = 10;
this b = 11;
}
void output ()
{
cout<<a<<” “<<b;
}
};
int main ()
{
X ob;
Ob.input ();
Ob.output ();
return 0;
}
Example 3:
#include<iostream>
#include<string.h>
using namespace std;
class person
{
char name[20];
6
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
float age;
public:
person(char s[],float a)
{
strcpy(name,s);
age=a;
}
int main()
{ char name1[10]="John";
char name2[10]="Jack";
char name3[10]= "Jim";
person P1(name1,37.50),P2(name2,29.0),P3(name3,40.25);
person P=P1.greater(P3);
P=P1.greater(P2);
7
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
Grand parent
Parent 1 Parent 2
Child
Here, inheritance by the “child” might pose some problems. All the public and protected
members of “grand parent” are inherited into child twice, first via “parent1” and again via
“parent2”.
This means, ‘child’ would have duplicate sets of the members inherited from grand parent. This
introduces ambiguity and should be avoided.
The duplication of inherited members due to these multiple paths can be avoided by making the
common base class as virtual base class .
Eg:
class A // grand parent
{
………………
………………
};
class B1: virtual public A // parent 1
{
………………
………………
};
class B2: public virtual // parent 2
{
………………
8
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
………………
};
class C: public B1, public B2 //child
{
………………
……………… // only one copy of a will be inherited.
};
Student
Test Sports
Results
#include<iostream>
using namespace std;
class student
{
protected:
int roll_number;
public:
void get_number(int a)
{
roll_number = a;
}
void put_number(void)
{
cout<<"Roll No:"<<roll_number<<"\n";
}
};
class test: virtual public student
{
protected:
float part1, part2;
public:
void get_marks (float x, float y)
9
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
{
part1 = x; part2 = y;
}
void put_marks(void)
{
cout <<"Marks obtained:"<<"\n"
<<"part1 = "<<part1<<"\n"
<<"part2 ="<<part2<<"\n";
}
};
10
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
student1.get_number (678);
student1.get_marks(30.5, 25.5);
student1.get_score(7.0);
student1.display();
}
Such function are called pure virtual function. A pure virtual function is a function declared in a
base class that has no definition relative to the base class .
A class containing pure virtual functions cannot be used to declare any objects of its own.
Eg:
class media
{
protected:
Char title [50];
float price;
public:
…………………
…………………
…………………
virtual void display () {} //empty virtual function
};
11
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
#include<iostream>
#include<string.h>
using namespace std;
class Person
{
protected:
char name[20];
int code;
public:
Person(){}
Person(char x[], int c)
{
strcpy(name,x);
code=c;
}
void showname()
{
cout<<"\nName of aperson is: "<<name;
cout<<"\nHis code is: "<<code;
}
};
class Account:public virtual Person
{
protected:
float pay;
public:
Account(float p)
{ pay=p; }
12
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
void showacc()
{
cout<<"\nPayment Given to him is: " <<pay;
}
};
class Admin:public virtual Person
{
protected:
float experience;
public:
Admin(float a)
{ experience=a; }
};
class Master:public Account, public Admin
{
public:
Master(char x[],int c,float p, float e): Person(x,c), Account(p),Admin(e) // These are function calls
{ }
void show()
{
showname();
showacc();
cout<<"\nHis years of Experience is: "<<experience;
}
};
int main()
{
Master m("Rohit Sharma",1011,50000,5.4);
m.show();
return 0;
}
Abstract classes:
An abstract class is one that is not used to create objects.
An abstract class is designed only to act as base class (to be inherited by other
classes).
It is a design concept in program development and provides a base upon which other
classes may be built.
Student
test Sport
Result 13
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
Here the student class is an abstract class since it is not used to create any objects.
Eg:
#include<iostream>
using namespace std;
class A
{
public:
virtual void show () = 0; // pure virtual function
};
class B: public A
{
public:
void show( ) // pure virtual function is overriden here
{
cout <<"show method is implemented here";
}
};
int main ()
{
A * ptr;
// ptr = new A; Cannot create instance of abstract class A
ptr = new B;
ptr->show( );
return 0;
}
Output:
show method is implemented here.
14
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
public:
virtual void printContent() = 0;
};
class Concrete {
private:
string info;
public:
Concrete(string s){
info = s;
}
void display() {
cout << "Concrete Object Information\n" << info << endl;
}
};
int main()
{
/*
* Abstract a;
* Error : Abstract Instance Creation Failed
*/
string s;
s = "This is concrete class";
Concrete c(s);
c. display();
return 0;
}
Overriding:
In inheritance relationship, a base class method is said to be overridden if a method is defined in
child class with same type, signature and name.
Eg:
#include<iostream>
using namespace std;
class A
{
public:
void show()
{
cout<<"\nbase class show";
}
};
class B: public A
{ public:
void show () //this method overridden base class method
{
cout<<"\nchild class show";
15
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
}
};
int main ()
{
B objB;
objB.show(); // show child class show
objB.A :: show(); // shows base class show
}
Friend Function
We know that the private member cannot be accessed from outside the class. That is, a non-
member-function cannot have an access to private data of a class. However, there could be a
situation where we would like two classes to share a particular function. In such situation C++
allows the common function to be made friendly with both the classes, thereby allowing the
function to have access to the private data of these classes. Such a function need not to be a
member of any of these classes.
To make outside function “friendly” to a class, we have to simply declare this function as a friend
of the class as shown below :
Class ABC
………..
…………
public:
……………
…………..
};
The functions that are declared with the keyword friend are known as friend functions.
A function can be declared as friend in any number of classes.
A friend function, although not a member function, has full access rights to the private members
of the class.
1) It is not in the scope of the class to which it has been declared as friend.
2) Since it is not in the scope of the class, it cannot be called using the object of that class.
3) It can be invoked like a normal function without the help of any object.
4) Usually, it has objects as arguments.
16
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
5) It cannot access the member names directly and has to use an object name and dot
membership operator with each member name (e.g A.x)
Example:
#include<iostream>
using namespace std;
class sample
{
int a;
int b;
public:
void setvalue( ) { a=25;b=40;}
friend float mean( sample s);
};
float mean (sample s)
{
return (float(s.a+s.b)/2.0);
}
int main ( )
{
sample x;
x . setvalue( );
cout<<"mean value="<<mean(x)<<endl;
return(0);
}
Member functions of one class can be friend function of another class. In such cases, they are defined
using the scope resolution operator.
E.g.
class X
{ ………..
………..
………..
};
class Y
{ …………..
……………
17
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
};
#include<iostream>
class abc;
class xyz
int x;
public:
void setvalue(int i) { x= i; }
};
class abc
int a;
public:
};
cout<<m.x;
else
cout<< n.a;
18
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
int main( )
abc j;
j . setvalue( 10);
xyz s;
s.setvalue(20);
max( s , j );
return(0);
#include<iostream>
using namespace std;
class E2;
class E3;
class E1
{ char name[10];
float salary;
public:
void set()
{
cout<<"\n Enter first Employee name and salary";
cin>>name>>salary;
}
friend void process(E1,E2,E3);
};
class E2
{
char name[10];
float salary;
public:
void set()
{
cout<<"\n Enter second Employee name and salary";
cin>>name>>salary;
}
friend void process(E1,E2,E3);
19
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
};
class E3
{
char name[10];
float salary;
public:
void set()
{
cout<<"\n Enter third Employee name and salary";
cin>>name>>salary;
}
friend void process(E1,E2,E3);
};
void process(E1 x, E2 y, E3 z)
{
cout<<"\n\nFirst Employee name= "<< x.name;
cout<<"\nFirst Employee salary= "<<x.salary;
int main()
{
E1 A;
E2 B;
E3 C;
A.set();
B.set();
C.set();
process(A,B,C);
return 0;
}
Output:
20
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
A static function can be called using the class-name (instead of its objects) as follows:
Class-name : : function-name
Example:
#include<iostream>
using namespace std;
class test
{
int code;
static int count; // static member variable
public:
void setcode(void)
{
code=++count;
}
void showcode(void)
{
cout<<"object member : "<<code<<endl;
}
static void showcount(void)
{ cout<<"count="<<count<<endl;
//cout<<code; //this can not be done here because static function will access only static variables
}
};
int main()
{
test t1,t2;
t1.setcode( );
21
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
t2.setcode( );
test :: showcount ( );
test t3;
t3.setcode( );
test:: showcount( );//accessing static member function
t1.showcode( );
t2.showcode( );
t3.showcode( );
//test t4;
//t4.showcount(); //it can also be done
return(0);
}
Output
Virtual Destructor
Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results
in undefined behavior. To correct this situation, the base class should be defined with a virtual
destructor. For example, following program results in undefined behavior
#include <iostream>
using namespace std;
class base {
public:
base()
{ cout << "Constructing base\n"; }
~base()
{ cout<< "Destructing base\n"; }
};
22
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
int main()
{
derived *d = new derived();
base *b = d;
delete b;
getchar();
return 0;
}
Output
Making base class destructor virtual guarantees that the object of derived class is destructed properly,
i.e., both base class and derived class destructors are called. For example,
#include <iostream>
using namespace std;
class base {
public:
base()
{ cout << "Constructing base\n"; }
virtual ~base()
{ cout << "Destructing base\n"; }
};
int main()
{
derived *d = new derived();
base *b = d;
delete b;
getchar();
return 0;
}
Output
23
Compiled By:
Er. Ranjan Raj Aryal
Amrit Campus
Note: As a guideline, any time you have a virtual function in a class, you should immediately add a
virtual destructor (even if it does nothing). This way, you ensure against any surprises later.
24