Upload
others
View
14
Download
0
Embed Size (px)
Citation preview
Unit – 4
Syllabus:- Operator Overloading, defining operator function, overloading unary, binary and relational
operators.
Inheritance, benefits of inheritance, types of inheritance, method overriding, virtual functions.
Chapter - 1
Operator Overloading:-
Introduction:- Operator Overloading is a specific case of Polymorphism ( part of the OO nature of the
language ) in which some or all operator like +, -, =, == etc., are treated as polymorphic functions and
as such have different behaviors depending on the type of its arguments (performing many actions with
a single operator).
Consider the following operation,
add ( a, multiply( b,c) ) – function notation
Using Operator Overloading permits a more concise(short) way of writing it a + b*c
Operators that are overloaded are listed below,
Aritmetic Operator
Relational Operator
Logical Operator
Assignment Operator
Unary Operator
Input and Output Operator
+ , - , * , / , %
< , <= , > , >= , != , ==
&& , !! , !
=
++ , -- , -
>> , <<
Operator that are not overloaded are listed below,
Size of Operator( sizeof )
Membership Operator( . )
Pointer to Member Operator( .* )
Scope Resolution Operator( :: ) and
Conditional Operators( ?: ) etc
Rules for Operator Overloading:-
1. Only existing operators can be overloaded. New operators cannot be overloaded.
2. The overloaded operator must have at least 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 follow the syntax rules of the original operators. They cannot be overridden.
5. There are some operators that cannot be overloaded like
Size of Operator( sizeof )
Membership Operator( . )
Pointer to Member Operator( .* )
Scope Resolution Operator( :: ) and
Conditional Operators( ?: ) etc
6. Binary operators overloaded through a member function take one explicit argument and those which
are overloaded through a friend function take two explicit arguments.
7. When using binary operators overloaded through a member function, the left hand operand must be
an object of the relevant class.
8. Binary arithmetic operators such as +,-,* and / must explicitly return a value. They must not attempt
to change their own arguments.
9. We cannot use “friend” functions to overload certain operators.However, member function can be
used to overload them.
10. Unary operators, overloaded by means of a member function, take no explicit arguments and return
no explicit values,
Defining Operator Function:-
To define an additional task to an operator, we must specify the relation to the class to which the
operator is applied. This is done with the help of special function called operator function.
The general form of an operator function is,
return-type class-name :: operator op (arglist)
{
//function body (task defined)
}
Here, return-type - type of returned by the specified operation
op - operator being overloaded(preceded by keyword operator and op is function name)
and
arglist- argument list
Operator functions must be either member function (non- static) or friend function. A basic difference
between that a
Friend Function will have only one argument for unary operators and two arguments for binary
operator.
Member Function have no arguments for unary operator and one argument for binary operator.
Operator functions are declared in the class using prototype as follows,
a) void operator ++ ( );
b) void operator -- ( );
c) void operator – ( ); d) num operator + ( num ); // binary operator using member function
e) friend num operator * ( int,num ); // binary operator using friend function
f) void operator = ( num ); // Assignment operator
The process of overloading involves the following steps:
1. Create a class that defines the data type that is to be used in the overloading operation.
2. Declare the operator function
i.e operator op( ) in the public part of the class( either member function or friend function).
3. Define the operator function to implement the require operations.
Overloaded operator functions can be invoked by expression
op X (or) X op Ex: ++ X; (or) X ++ ;
Overloading Unary Operator:-
Overloading without explicit argument to an operator function is called as unary operator
overloading
The operator ++ ( increment ), -- (decrement), - (minus) are unary operators.
The unary operator ++, --, - can be used prefix or suffix with the functions.
i.e ++ X or X ++
These operators have only single operand( called as unary operator)
Syntax:
return-type class-name :: operator operator-symbol ( )
{
// body of function
}
Example:-
Explanation:- The operator ++( ) overloads the unary operators ++. When the operator is used with
integer (or) float variables, it’s value is increased by “1”. In this function, ++ operator preceded each
member variable in class.
In main( ), the statement ++n1 calls the function operator ++ ( ), where n1 is an object of the class num.
#include<iostream.h>
#include<conio.h>
class num
{
private:
int a,b,c,d;
public:
num(int p,int q,int r,int s)
{
a=p;
b=q;
c=r;
d=s;
}
void display()
{
cout<<"A="<<a;
cout<<" B="<<b;
cout<<" C="<<c;
cout<<" D="<<d;
}
void operator ++();
};
void num :: operator ++()
{
a=++a;
b=++b;
c=++c;
d=++d;
}
void main()
{
clrscr();
num n1(10,20,30,40);
cout<<"Before Increment..."<<endl;
n1.display();
++n1;
cout<<"After Increment..."<<endl;
n1.display();
getch();
}
Output:-
Before Increment...
A=10 B=20 C=30 D=40
After I re e t…
A=11 B=21 C=31 D=41
Overloading Binary Operator:-
Overloading with a single parameter is called as binary operator overloading.
Like unary operator, binary operators can also be overloaded.
Binary operator requires two operands.
It can also be overloaded using member function and friend function.
1. Overloading Binary Operator using member function:-
In member function they require one argument to overload.
The argument contains the value of the object which is right side of the operator.
If we want to perform the addition of two object o1 and o2 then,
operator (num o2)
Here, num is class-name, o2 is an object
To call function operator, the statement as,
o3 = o1 operator-name o2 ;
Here, the data member o1 passed directly and o2 passed as argument.
2. Overloading Binary Operator using friend function:
The friend function requires two operands to be passed as arguments.
o3 = o1 + o2;
o3 = operator + (o1,o2);
Both the statements have the same meaning. In the second statement, two objects are passed to the
operator function.
Syntax:
return-type operator operator-symbol (argument list)
{
// body of function
}
Write After diagram:
As a rule, in overloading of binary operators, the left-hand operand is used to invoke the operator
function and the right-hand operand is passed as an argument.
We can avoid the creation of the temp object by replacing the entire function body by the following
statement: return complex ( ( a + k.a ),( b + k.b ) );
Overloading Relational Operator:-
There are various relational operators supported by c++ language, which can be used to compare c++
built-in data types.
For example,
a) Less than ( < )
b) Less than or equal to ( < = )
c) Greater than ( > )
d) Greater than or equal to ( > = )
e) Equal to ( == )
f) Not equal to ( != )
We can overload any of these operators, which can be used to compare the object of the class.
Following example explains how a ‘ < ’ operator can be overloaded and similar way you can
overload other relational operator.
Syntax:- return-type class-name :: operator operator-name (arglist)
{
// body of function
}
Example:-
Explanation:- In the above program, from main( ) relational operator function (<) is invoked and return
the value. i.e ,n1 object value is 10 and n2 object value is 20. It checks condition and return
corresponding value ( either true = 1 or false = 0 ). Finally it return 1 from operator function to main()
and display true condition i.e “n1 is less than n2”.
#include<iostream.h>
#include<conio.h>
class num
{
private:
int a;
public:
num(int x)
{
a = x;
}
int operator < (num k)
{
return ( a < k.a);
}
};
void main()
{
clrscr();
num n1(10),n2(20);
if(n1<n2)
{
cout<<"n1 is less than n2";
}
else
{
cout<<"n1 is greater than n1";
}
getch();
}
Output:-
n1 is less than n2
Chapter 2
INHERITANCE:-
Introduction:-
One of the most important concepts in Object Oriented Programming is that of
Inheritance. Inheritance allows us to define one class items to another class, which makes easier to
create and maintain on application. This also provides an opportunity to reuse the code functionality
and fast implementation time.
When creating a class, instead of writing completely new data members and member
function, the programmer can designate that the new class should inherit the members of an existing
class. This existing class is called the “Base Class” and the new class is referred as the “Derived Class”.
Definition of Inheritance:-
Inheritance in Object Oriented Programming can be described as process of creating a
new class from existing classes. New Classes inherit some of the properties (member variables) and
behavior (member functions) of the existing classes. An existing class that is “parent” of a new class is
called a “child”
Note: Base class / Super class / Parent class are same
Derived class / sub class / child class are same
The General Form of a defining derived class is
Class Derive-class-name : Visibility-mode Base-class-name
{
--------- // member of derived class
};
Benefits of Inheritance:-
One of the key benefits of inheritance is to minimize the amount of duplicate code in an
application by sharing common code amongst several subclasses.
Inheritance can also make application code more flexible to change because classes that
inherit from a common superclass can be used interchangeably.
Reusability - facility to use public methods of base class without rewriting the same.
Extensibility - extending the base class logic as per business logic of the derived class.
Data hiding - base class can decide to keep some data private so that it cannot be altered by
the derived class
Overriding -With inheritance, we will be able to override the methods of the base class so
that meaningful implementation of the base class method can be designed in the derived class.
Disadvantage of Inheritance:-
1. Main disadvantage of using inheritance is that the two classes (base and inherited class) get tightly
coupled. This means one cannot be used independent of each other.
2. Also with time, during maintenance adding new features both base as well as derived classes are
required to be changed. If a method signature is changed then we will be affected in both cases
(inheritance & composition).
3. If a method is deleted in the "super class" or aggregate, then we will have to re-factor in case of
using that method.
4. It increased time/effort it takes the program to jump through all the levels of overloaded classes.
Types of Inheritance:-
A class can inherit properties (data) and behaviours (functions) in various levels used for
derivation. In c++, there are six types of inheritance, that are listed below,
1. Single Inheritance Example:- Single Inheritance
2. Multiple Inheritance
3. Hierarchical Inheritance
4. Multi-level Inheritance
5. Hybrid Inheritance and
6. Multi-Path Inheritance
1. Single Inheritance:-
When only one base class is used for derivation of a
class is not used as base class, such type of inheritance
between one base and derived class is known as inheritance.
fig. Single Inheritance
Here, A is base class, B is derived class.
Further no class derived from B.
#include<iostream.h>
#include<conio.h>
class A
{
protected:
int id;
};
class B : public A
{
private:
char name[20];
public:
void getdata()
{
cout<<"\nEnter ID and Name: ";
cin>>id>>name;
}
void display()
{
cout<<"ID:"<<id<<endl<<"Name:"<<name;
}
};
void main()
{
clrscr();
B b;
b.getdata();
b.display();
getch();
}
A
B
Output:-
Enter ID and Name: 10 Rahul
ID: 10
Name: Rahul
Syntax:- Example:- Multiple Inheritance
class base-class-name
{
---------//base class members
};
class derived-class-name : visibility-mode base-class-name
{
--------- //derived class members
};
2. Multiple Inheritance:-
When two or more base class are used for
derivation of a class, it is called multiple inheritance.
fig. Multiple Inheritance
class C inherits properties of both A and B base class,
further C is not used for base class.
Syntax:-
class base-class-name1
{
------ //base class members
};
class base-class-name2
{
----- //base class members
};
class derived-class-name : visibility-mode base-class-name1, base-class-name2
{
----- //derived class members
};
#include<iostream.h>
#include<conio.h>
class A
{
protected:
int id;
};
class B
{
protected:
char name[20];
};
class C : public A,B
{
private:
float height;
public:
void getdata()
{
cout<<"Enter ID,name and height:";
cin>>id>>name>>height;
}
void display()
{
cout<<"ID:"<<id<<endl<<"Name:"<<name<<endl<
<"Height:"<<height;
}
};
void main()
{
clrscr();
C c;
c.getdata();
c.display();
getch();
}
A B
C
Output:-
Enter ID, Name and Height:
10 Rahul 5.11
ID: 10
Name: Rahul
Height: 5.11
3. Hierarchical Inheritance:- Example:- Hierarchical Inheritance
When a single base class is used to derivation of
two or more classes, it is known as
hierarchical inheritance
fig. Hierarchical Inheritance
Here, A is base class and B, C are derived class.
Further B and C are not used for deriving class.
Syntax:-
class base-class-name1
{
----- // base class members
};
class derived-class-name1 : visibility-mode
base-class-name
{
------//derived class-name1 members
};
class derived-class-name2 : visibility-mode
base-class-name
{
------//derived class-name2 members
};
#include<iostream.h>
#include<conio.h>
class A
{
protected:
int id;
};
class B : public A
{
protected:
char name[20];
};
class C : public A
{
private:
float height;
public:
void getdata()
{
cout<<"Enter ID and Height:";
cin>>id>>height;
}
void display()
{
cout<<"ID:"<<id<<endl<<"Height:"<<height;
}
};
void main()
{
clrscr();
C c;
c.getdata();
c.display();
getch();
}
A
B C
Output:-
Enter ID and Height: 10 5.11
ID: 10
Height: 5.11
4. Multi-Level Inheritance:- Example:- Multilevel inheritance
When a class is derived from another derived class
i.e. derived class act as base class. Such types of inheritance
is known as multi-level inheritance.
Fig. Multi-level inheritance
Here, B is derived class from class A(base class).
Again B acts as base class to class C, which is derived class.
Finally, there is no more derivation from class C.
Syntax:-
class base-class-name1
{
----- //class-name1 members
};
class intermediate-base-class-name2 : visibility-mode
base-class-name1
{
----- //class-name2 members
};
class derived-class-name3 : visibility-mode
intermediate-base-class-name2
{
----- //clas-name3 members
};
#include<iostream.h>
#include<conio.h>
class A
{
protected:
int id;
};
class B : public A
{
protected:
char name[20];
};
class C : public B
{
private:
float height;
public:
void getdata()
{
cout<<"Enter id,name and height:";
cin>>id>>name>>height;
}
void display()
{
cout<<"ID:"<<id<<endl;
cout<<"Name:"<<name<<endl;
cout<<"Height:"<<height;
}
};
void main()
{
clrscr();
C c;
c.getdata();
c.display();
getch();
}
A
B
C
Output:-
Enter id, name and height: 10 Rahul 5.11
ID: 10
Name: Rahul
Height: 5.11
5. Hybrid Inheritance:- Example:- Hybrid Inheritance
Combining more than one type of inheritance is known
as Hybrid Inheritance.
i.e. here, combining Multi-Level and Single Inheritance
Fig. Hybrid Inheritance
Here, class B acts as derived class for class A and base class
for class C. C is derived class form class B and class D.
Syntax:
class base-class-name1
{
----- //class-name1 members
};
class intermediate-base-class-name2 : visibility-mode
base-class-name1
{
----- //class-name2 members
};
class base-class-name3
{
----- //class-name3 members
};
class derived-class-name4 : visibility-mode
intermediate-base-class-name2,base-class-name3
{
----- //derived-class-name4 members
};
#include<iostream.h>
#include<conio.h>
class A
{
protected:
int id;
};
class B : public A
{
protected:
char name[20];
};
class C
{
protected:
float height;
};
class D : public B,C
{
private:
float weight;
public:
void getdata()
{
cout<<"Enter id,name,height and
weight:";
cin>>id>>name>>height>>weight;
}
void display()
{
cout<<"ID:"<<id<<endl;
cout<<"Name:"<<name<<endl;
cout<<"Height:"<<height<<endl;
cout<<"Weight:"<<weight<<endl;
}
};
void main()
{
clrscr()
D d;
d.getdata();
d.display();
getch();
}
A
B
C
D
Output:
Enter id,name,height and weight:
10 Rahul 5.11 78.5
ID: 10
Name: Rahul
Height: 5.11
Weight: 78.5
6. Multi-Path Inheritance:- Example:- Multipath Inheritance
When a class is derived from two (or) more classes that are
derived from same base class, such type of inheritance
is known as Multi-Path Inheritance.
Fig. Multi-Path Inheritance
Here, class B and C acts as derived class for base class A
and base class for class D.
i.e class D is derived from class B and C.
While executing the program, ambiguity is generated.
Hence, virtual keyword is used to avoid ambiguity.
Syntax:-
class base-class-name1
{
----- // base class members
};
class derived-class-name1 : visibility-mode
base-class-name1
{
------//derived class-name1 members
};
class derived-class-name2 : visibility-mode
base-class-name1
{
------//derived class-nam2 members
};
class derived-class-name3 : visibility-mode
derived-class-name1,derived-class-name2
{
----- //derived class-name3 member
};
#include<iostream.h>
#include<conio.h>
class A
{
protected:
int id;
};
class B : virtual public A
{
protected:
char name[20];
};
class C : virtual public A
{
protected:
float height;
};
class D : public B,C
{
private:
float weight;
public:
void getdata()
{
cout<<"Enter id,name,height and
weight:";
cin>>id>>name>>height>>weight;
}
void display()
{
cout<<"ID:"<<id<<endl;
cout<<"Name:"<<name<<endl;
cout<<"Height:"<<height<<endl;
cout<<"Weight:"<<weight<<endl;
}
};
void main()
{
clrscr();
D d;
d.getdata();
d.display();
getch();
}
A
B C
D
Output:
Enter id,name,height and weight:
10 Rahul 5.11 78.5
ID: 10
Name: Rahul
Height: 5.11
Weight: 78.5
Method Overriding (or) Function Overriding:-
Inheritance allows software developers to derive a new class from the existing class. The derive class
inherits features of base class (existing class).
Suppose, both base class and derived class have a member function with same name and arguments
(number and type of arguments)
If you create an object of the derived class and call the member function which exists in both classes
(base and derived) , the member function of the derive class in invoked and the function of base class
is ignored.
This feature in c++ is known as Method Overriding (or) Function Overriding.
Example 1:-
To access the overridden function of the base class from the derive class, scope resolution
operator ( :: ) is used. i.e. d.Base :: display(); // now member function in base class is also executed.
#include<iostream.h>
#include<conio.h>
class Base
{
public:
void display()
{
cout<<"The member function in Base Class..."<<endl;
}
};
class Derived : public Base
{
public:
void display()
{
cout<<"The member function in Derived Class..."<<endl;
}
};
void main()
{
clrscr();
Derived d;
d.display();
getch();
}
Output:-
The e er fu tio i Derived Class…
Example 2:- Example 3:-
In example 2, we access base class member function from derive class
In example 3, we access base class member function from main( ) using derived class object.
#include<iostream.h>
#include<conio.h>
class Base
{
public:
void display()
{
cout<<"The member function in Base
Class..."<<endl;
}
};
class Derived : public Base
{
public:
void display()
{
cout<<"The member function in Derived
Class..."<<endl;
}
};
void main()
{
clrscr();
Derived d;
d.display();
d.Base::display();
getch();
}
Output:-
The e er fu tio i Derived Class…
The e er fu tio i Base Class…
#include<iostream.h>
#include<conio.h>
class Base
{
public:
void display()
{
cout<<"The member function in Base Class..."<<endl;
}
};
class Derived : public Base
{
public:
void display()
{
Base::display();
cout<<"The member function in Derived Class..."<<endl;
}
};
void main()
{
clrscr();
Derived d;
d.display();
getch();
}
Output:-
The e er fu tio i Base Class…
The e er fu tio i Derived Class…
Virtual Function:-
1. An essential requirement of polymorphism is the ability to refer to objects without any regard of their
classes.
2. This makes necessary to use a single pointer variable to refer to the objects of different classes.
3. Here, we use the pointer to the base class, to refer to all the derived objects.
4. But, when it is made to contain address of a derived class, always executes the function in base class.
The compiler simply ignores the contents of the pointer and chooses the member function that
matches the type of the pointer.
5. To overcome such thing, we using the function called virtual function.
6. When we use the same function name in both the base and derived class(method overriding), the
function in base class is declared as virtual by using the keyword ‘virtual’ preceding its normal
declaration.
7. When a function is made virtual, c++ determines the functions to use at run-time based on type of
object pointed by the base pointer ( late binding ).
8. Thus, by making the base pointer to point to the different object, we can execute different version of
virtual function.
Example:-
#include<iostream.h>
#include<conio.h>
class Base
{
public:
virtual void display()
{
cout<<"Display Base class..."<<endl;
}
};
class Derived : public Base
{
public:
void display()
{
cout<<"Display Derived class..."<<endl;
}
};
void main()
{
clrscr();
Base b;
Derived d;
Base *p;
p=&b;
p ->display();
p =&d;
p ->display();
getch();
}
Output:-
Display Base lass…
Display Derived lass…