Program : B.
Tech
Subject Name: Object Oriented Programming & Methodology
Subject Code: IT-304
Semester: 3rd
Downloaded from be.rgpvnotes.in
UNIT III
Overloading in C++
C++ allows you to specify more than one definition for a function name or an operator in the same scope,
which is called function overloading and operator overloading respectively.
An overloaded declaration is a declaration that had been declared with the same name as a previously
declared declaration in the same scope, except that both declarations have different arguments and
obviously different definition (implementation).
When you call an overloaded function or operator, the compiler determines the most appropriate
definition to use by comparing the argument types you used to call the function or operator with the
parameter types specified in the definitions. The process of selecting the most appropriate overloaded
function or operator is called overload resolution.
Function overloading in C++
You can have multiple definitions for the same function name in the same scope. The definition of the
function must differ from each other by the types and/or the number of arguments in the argument list.
You cannot overload function declarations that differ only by return type.
Following is the example where same function print() is being used to print different data types:
#include <iostream>
using namespace std;
classprintData {
public:
void print(int i) {
cout<< "Printing int: " << i <<endl;
}
void print(double f) {
cout<< "Printing float: " << f <<endl;
}
void print(char* c) {
cout<< "Printing character: " << c <<endl;
}
};
int main(void) {
printDatapd;
// Call print to print integer
pd.print(5);
// Call print to print float
pd.print(500.263);
// Call print to print character
pd.print("Hello C++");
return 0;
}
Page no: 1 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
Overloading unary operators
The u ar operators operate o a si gle opera d a d follo i g are the e a ples of U ar operators −
The increment (++) and decrement (--) operators.
The unary minus (-) operator.
The logical not (!) operator.
The unary operators operate on the object for which they were called and normally, this operator appears
on the left side of the object, as in !obj, -obj, and ++obj but sometime they can be used as postfix as well
like obj++ or obj--.
Following example explain how minus (-) operator can be overloaded for prefix as well as postfix usage.
#include <iostream>
using namespace std;
class Distance {
private:
int feet; // 0 to infinite
int inches; // 0 to 12
public:
// required constructors
Distance() {
feet = 0;
inches = 0;
}
Distance(int f, int i) {
feet = f;
inches = i;
}
// method to display distance
voiddisplayDistance() {
cout<< "F: " << feet << " I:" << inches <<endl;
}
// overloaded minus (-) operator
Distance operator- () {
feet = -feet;
inches = -inches;
return Distance(feet, inches);
}
};
int main() {
Distance D1(11, 10), D2(-5, 11);
-D1; // apply negation
D1.displayDistance(); // display D1
Page no: 2 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
-D2; // apply negation
D2.displayDistance(); // display D2
return 0;
}
When the above code is compiled and executed, it produces the following result −
F: -11 I:-10
F: 5 I:-11
Overloading binary operators
The binary operators take two arguments and following are the examples of Binary operators. You use
binary operators very frequently like addition (+) operator, subtraction (-) operator and division (/)
operator.
Following example explains how addition (+) operator can be overloaded. Similar way, you can overload
subtraction (-) and division (/) operators.
#include <iostream>
using namespace std;
class Box {
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
public:
doublegetVolume(void) {
return length * breadth * height;
}
voidsetLength( double len ) {
length = len;
}
voidsetBreadth( double bre ) {
breadth = bre;
}
voidsetHeight( double hei ) {
height = hei;
}
// Overload + operator to add two Box objects.
Box operator+(const Box& b) {
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
Page no: 3 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
box.height = this->height + b.height;
return box;
}
};
// Main function for the program
int main() {
Box Box1; // Declare Box1 of type Box
Box Box2; // Declare Box2 of type Box
Box Box3; // Declare Box3 of type Box
double volume = 0.0; // Store the volume of a box here
// box 1 specification
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// box 2 specification
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// volume of box 1
volume = Box1.getVolume();
cout<< "Volume of Box1 : " << volume <<endl;
// volume of box 2
volume = Box2.getVolume();
cout<< "Volume of Box2 : " << volume <<endl;
// Add two object as follows:
Box3 = Box1 + Box2;
// volume of box 3
volume = Box3.getVolume();
cout<< "Volume of Box3 : " << volume <<endl;
return 0;
}
Whe the a o e ode is o piled a d e e uted, it produ es the follo i g result −
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
Data Conversion and Pitfalls of Operators Overloading
Data conversion in C++ includes conversions between basic types and user-defined types, and conversions
between different user-defined types.
The assignments between types, whether they are basic types or user-defined types, are handled by the
Page no: 4 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
compiler with no effort on our part, provided that the same data type is used on both sides of the equal
sign.
The different possible data conversion situations are:
1. Conversion between basic and user defined
a) Conversion from basic to user defined data type
b) Conversion from user-defined data type to basic data type
1. Conversion between basic and user defined
(a) Conversion from basic to user defined data type
Conversion from basic to user defined type is done by using the constructor function with one argument of
basic type as follows.
Syntax:
classclass_name {
private:
//….
public:
class_name( data_type) {
// conversion code
}
};
Here is program that illustrates this conversion.
//example
//conversion from basic type to object
#include<iostream>
using namespace std;
classcelsius
{
private:
float temper;
public:
celsius()
{
temper=0;
} celsius(float ftmp)
{
temper=(ftmp-32)* 5/9;
}
voidshowtemper()
{
cout<<"Temperature in Celsius: "<<temper;
}
};
int main()
{
celsiuscel; //cel is user defined
floatfer; //fer is basic type
Page no: 5 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
cout<<"\nEnter temperature in Fahrenheit measurement: ";
cin>>fer;
cel=fer; //convert from basic to user-defined; //eqvt to cel = celsius(fer);
cel.showtemper();
return 0;
}
The output of the program is:
Enter temperature in Fahrenheit measurement: -40
Temperature in Celsius: -40
(b) Conversion from user-defined type to basic data type
Conversion from user-defined type of basic data type is done by overloading the cast operator of basic
type as a member function.
Operator function is defined as an overloaded basic data type which takes no arguments.
Return type of operator is not specified because the cast operator function itself specifies the return type.
Syntax:
classclass_name {
...
public:
operatordata_type() {
//Conversion code
}
};
Here is example program to illustrate conversion from user-defined type of basic data type.
//conversion from user to basic type
#include<iostream>
using namespace std;
classcelsius
{
private:
float temper;
public:
celsius()
{
temper=0;
}
operator float()
{
floatfer;
fer=temper *9/5 + 32;
return (fer);
}
voidgettemper()
{
cout<<"\n Enter Temperature in Celsius:";
cin>>temper;
}
Page no: 6 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
};
int main()
{
celsiuscel; //cel is user defined
floatfer; //fer is basic type
cel.gettemper();
fer=cel; //convert from user-defined to basic;
//eqvtto fer= float(cel);
cout<<"\nTemperature in Fahrenheit measurement: "<<fer;
}
The output of the program is:
Enter Temperature in Celsius: -40
Temperature in Fahrenheit measurement: -40
Restrictions on Operator Overloading
• Precedence and Associativity of an operator cannot be changed.
Following are some restrictions to be kept in mind while implementing operator overloading.
• The numbers of Operands cannot be changed. Unary operator remains unary, binary remains
• No new operators can be created, only existing operators can be overloaded.
binary etc.
• Cannot redefine the meaning of a procedure. You cannot change how integers are added.
Inheritance
One of the most important concepts in object-oriented programming is that of inheritance. Inheritance
allows us to define a class in terms of another class, which makes it easier to create and maintain an
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 functions, 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 to as the derived class.
The idea of inheritance implements the is a relationship. For example, mammal IS-A animal, dog IS-A
mammal hence dog IS-A animal as well and so on.
Base & Derived Classes
A class can be derived from more than one classes, which means it can inherit data and functions from
multiple base classes. To define a derived class, we use a class derivation list to specify the base class(es). A
class derivation list names one or more base classes and has the form:
class derived-class: access-specifier base-class
Where access-specifier is one of public, protected, or private, and base-class is the name of a previously
defined class. If the access-specifier is not used, then it is private by default.
Consider a base class Shape and its derived class Rectangle as follows:
#include <iostream>
Page no: 7 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
using namespace std;
// Base class
class Shape {
public:
voidsetWidth(int w) {
width = w;
}
voidsetHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// Derived class
class Rectangle: public Shape {
public:
intgetArea() {
return (width * height);
}
};
int main(void) {
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout<< "Total area: " <<Rect.getArea() <<endl;
return 0;
}
Access Modifiers
Access public protected private
Same class yes yes yes
Derived classes yes yes no
Outside classes yes no no
• Reduce code redundancy.
Advantages
• Provides code reusability.
• Reduces source code size and improves code readability.
• Code is easy to manage and divided into parent and child classes.
• Supports code extensibility by overriding the base class functionality within child classes.
Disadvantages
Page no: 8 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
• In Inheritance base class and child classes are tightly coupled. Hence If you change the code of
•
parent class, it will get affects to the all the child classes.
In class hierarchy many data members remain unused and the memory allocated to them is not
utilized. Hence affect performance of your program if you have not implemented inheritance
correctly.
Types of Inheritance
1. Single inheritance
In this inheritance, a derived class is created from a single base class.
//Base Class
class A
{
public void fooA()
{
//TO DO:
}
}
//Derived Class
class B : A
{
public void fooB()
{
//TO DO:
}
}
2. Multi-level inheritance
In this inheritance, a derived class is created from another derived class.
//Base Class
class A
{
public void fooA()
{
//TO DO:
}
}
//Derived Class
class B : A
{
public void fooB()
{
//TO DO:
}
}
//Derived Class
class C : B
{
public void fooC()
Page no: 9 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
{
//TO DO:
}
}
3. Multiple inheritance
In this inheritance, a derived class is created from more than one base class. This inheritance is not
supported by .NET Languages like C#, F# etc.
//Base Class
class A
{
public void fooA()
{
//TO DO:
}
}
//Base Class
class B
{
public void fooB()
{
//TO DO:
}
}
//Derived Class
class C : A, B
{
public void fooC()
{
//TO DO:
}
}
4. Hierarchical inheritance
In this inheritance, more than one derived classes are created from a single base.
//Base Class
class A
{
public void fooA()
{
//TO DO:
}
}
//Derived Class
class B : A
{
public void fooB()
{
//TO DO:
Page no: 10 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
}
}
//Derived Class
class C : A
{
public void fooC()
{
//TO DO:
}
}
//Derived Class
class D : C
{
public void fooD()
{
//TO DO:
}
}
//Derived Class
class E : C
{
public void fooE()
{
//TO DO:
}
}
//Derived Class
class F : B
{
public void fooF()
{
//TO DO:
}
}
//Derived Class
class G :B
{
public void fooG()
{
//TO DO:
}
}
5. Hybrid inheritance
This is combination of more than one inheritance. Hence, it may be a combination of Multilevel and
Multiple inheritances or Hierarchical and Multilevel inheritance or Hierarchical and Multipath inheritance
or Hierarchical, Multilevel and Multiple inheritances.
Since .NET Languages like C#, F# etc. does not support multiple and multipath inheritance. Hence hybrid
inheritance with a combination of multiple or multipath inheritance is not supported by .NET Languages.
Page no: 11 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
//Base Class
class A
{
public void fooA()
{
//TO DO:
}
}
//Base Class
class F
{
public void fooF()
{
//TO DO:
}
}
//Derived Class
class B : A, F
{
public void fooB()
{
//TO DO:
}
}
//Derived Class
class C : A
{
public void fooC()
{
//TO DO:
}
}
//Derived Class
class D : C
{
public void fooD()
{
//TO DO:
}
}
//Derived Class
class E : C
{
public void fooE()
{
//TO DO:
}
}
Page no: 12 Follow us on facebook to get real-time updates from RGPV
Downloaded from be.rgpvnotes.in
Derived class constructors
A constructor plays a vital role in initializing an object. An important note, while using constructors during
inheritance, is that, as long as a base class constructor does not take any arguments, the derived class need
not have a constructor function. However, if a base class contains a constructor with one or more
arguments, then it is mandatory for the derived class to have a constructor and pass the arguments to the
base class constructor. When both the derived and base class contains constructors, the base constructor
is executed first and then the constructor in the derived class is executed.
In case of multiple inheritance, the base class is constructed in the same order in which they appear in the
declaration of the derived class. Similarly, in a multilevel inheritance, the constructor will be executed in
the order of inheritance.
The derived class takes the responsibility of supplying the initial values to its base class. The constructor of
the derived class receives the entire list of required values as its argument and passes them on to the base
constructor in the order in which they are declared in the derived class. A base class constructor is called
and executed before executing the statements in the body of the derived class.
Public and Private Inheritance
When deriving a class from a base class, the base class may be inherited through public, protected or
private inheritance. The type of inheritance is specified by the access-specifier as explained above.
We hardly use protected or private inheritance, but public inheritance is commonly used. While using
different type of inheritance, following rules are applied:
Public Inheritance: When deriving a class from a public base class, public members of the base class
become public members of the derived class and protected members of the base class become protected
members of the derived class. A base class's private members are never accessible directly from a derived
class, but can be accessed through calls to the public and protected members of the base class.
Protected Inheritance: When deriving from a protected base class, public and protected members of the
base class become protected members of the derived class.
Private Inheritance: When deriving from a private base class, public and protected members of the base
class become private members of the derived class.
Page no: 13 Follow us on facebook to get real-time updates from RGPV
We hope you find these notes useful.
You can get previous year question papers at
https://qp.rgpvnotes.in .
If you have any queries or you want to submit your
study notes please write us at
[email protected]