Download as pdf or txt
Download as pdf or txt
You are on page 1of 21

Unit – III

The keyword operator


To overload an operator, a special operator function is defined inside the class as:

class className
{
... .. ...
public
returnType operator symbol (arguments)
{
... .. ...
}
... .. ...
};

 Here, returnType is the return type of the function.


 The returnType of the function is followed by operator keyword.
 Symbol is the operator symbol you want to overload. Like: +, <, -, ++
 You can pass arguments to the operator function in similar way as functions.

Overloadable/Non-overloadableOperators

Following is the list of operators which can be overloaded:

+ - * / % ^

& | ~ ! , =

< > <= >= ++ --

<< >> == != && ||

+= -= /= %= ^= &=

|= *= <<= >>= [] ()

CPP Notes Page 1


Unit – III

-> ->* new new [] delete delete []

Following is the list of operators, which can not be overloaded:

:: .* . ?:

Example

#include <iostream>
using namespace std;

class Test
{
private:
int count;

public:
Test(): count(5){}

void operator ++()


{
count = count+1;
}
void Display() { cout<<"Count: "<<count; }
};

int main()
{
Test t;
// this calls "function void operator ++()" function
++t;
t.Display();
return 0;
}

CPP Notes Page 2


Unit – III

Overloading Unary Operator


The unary operators operate on a single operand and following are the examples of Unary
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
void displayDistance() {
cout << "F: " << feet << " I:" << inches <<endl;
}
// overloaded minus (-) operator
Distance operator- () {
feet = -feet;
inches = -inches;

CPP Notes Page 3


Unit – III

return Distance(feet, inches);


}
};

int main() {
Distance D1(11, 10), D2(-5, 11);

-D1; // apply negation


D1.displayDistance(); // display D1

-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

Hope above example makes your concept clear and you can apply similar concept to overload
Logical Not Operators.

The increment (++) and decrement (--) operators are two important unary operators
available in C++.

Following example explain how increment (++) operator can be overloaded for prefix as well as
postfix usage. Similar way, you can overload operator (--).

#include <iostream>
using namespace std;
class Time {
private:
int hours; // 0 to 23
int minutes; // 0 to 59
public:
// required constructors
Time(){
hours = 0;
CPP Notes Page 4
Unit – III

minutes = 0;
}
Time(int h, int m){
hours = h;
minutes = m;
}
// method to display time
void displayTime() {
cout << "H: " << hours << " M:" << minutes <<endl;
}
// overloaded prefix ++ operator
Time operator++ () {
++minutes; // increment this object
if(minutes >= 60) {
++hours;
minutes -= 60;
}
return Time(hours, minutes);
}
// overloaded postfix ++ operator
Time operator++( int ) {
// save the orignal value
Time T(hours, minutes);
// increment this object
++minutes;

if(minutes >= 60) {


++hours;
minutes -= 60;
}
// return old original value
return T;
}
};

int main() {
Time T1(11, 59), T2(10,40);

++T1; // increment T1
T1.displayTime(); // display T1
++T1; // increment T1 again
T1.displayTime(); // display T1

CPP Notes Page 5


Unit – III

T2++; // increment T2
T2.displayTime(); // display T2
T2++; // increment T2 again
T2.displayTime(); // display T2
return 0;
}

When the above code is compiled and executed, it produces the following result:

H: 12 M:0

H: 12 M:1

H: 10 M:41

H: 10 M:42

Operator Return Type


It is possible to return value and assign to it other object of the same type. The return
value of operator is always of class type, because the operator overloading is only for objects.
An operator cannot be overloaded for basic data types. Hence, if the operator returns any value,
it will be always of class type.

Example:

#include<conio.h>
#include<iostream.h>
class num
{
private:
int a,b,c,d;
public:
void input(void);
void show(void);
friend num operator * (num);
};
void num :: input()
{
cout<<"\nEnter Value for a,b,c and d:";
cin>>a>>b>>c>>d;
}
void num :: show()

CPP Notes Page 6


Unit – III

{
cout<<"\nA="<<a<<"\nB="<<b<<"\nC="<<c<<"\nD="<<d;
}
num operator * (num t)
{
num tmp;
tmp.a = a * t.a;
tmp.b = b * t.b;
tmp.c = c * t.c;
tmp.d = d * t.d;
return tmp;
}
int main()
{
clrscr();
num x,y,z;
cout<<"\nObject X:";
x.input();
cout<<"\nObjecy Y:";
y.input();
z = x*y;
cout<<"\nX:";
x.show();
cout<<"\nY:";
y.show();
cout<<"\nZ:";
z.show();
getch();
return 0;
}

Rules for overloading operators


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.

CPP Notes Page 7


Unit – III

5. There are some operators that cannot be overloaded like size of operator(sizeof), membership
operator(.), pointer to member operator(.*), scope resolution operator(::), conditional
operators(?:) etc

6. We cannot use “friend” functions to overload certain operators.However, member function


can be used to overload them. Friend Functions can not be used with assignment operator(=),
function call operator(()), subscripting operator([]), class member access operator(->) etc.

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 a friend function, take one reference
argument (the object of the relevent class).

8. Binary operators overloaded through a member function take one explicit argument and those
which are overloaded through 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.

11. Some operators like (assignment)=, (address)& and comma (,) are by default overloaded.

Overloading Assignment Operator

1. Assignment Operator is Used to assign value to an variable.


2. Assignment operator is denoted by equal to sign.
3. Assignment operator have Two values L-Value and R-value. Operator copies R-Value
into L-Value.
4. It is a binary operator.

C++ Overloading Assignment Operator

1. C++ Overloading assignment operator can be done in object oriented programming.


2. By overloading assignment operator, all values of one object (i.e instance variables) can
be copied to another object.
3. Assignment operator must be overloaded by a non-static member function only.
4. If the overloading function for the assignment operator is not written in the class, the
compiler generates the function to overload the assignment operator.
Syntax
Return_Type operator = (const Class_Name &)
Example:
CPP Notes Page 8
Unit – III

#include<iostream>
using namespace std;

class Marks
{
private:
int m1;
int m2;

public:

//Default constructor
Marks() {
m1 = 0;
m2 = 0;
}

// Parametrised constructor
Marks(int i, int j) {
m1 = i;
m2 = j;
}

// Overloading of Assignment Operator


void operator=(const Marks &M ) {
m1 = M.m1;
m2 = M.m2;
}

void Display() {
cout << "Marks in 1st Subject:" << m1;
cout << "Marks in 2nd Subject:" << m2;
}
};

int main()
{
// Make two objects of class Marks
Marks Mark1(45, 89);
Marks Mark2(36, 59);

cout << " Marks of first student : ";


Mark1.Display();

CPP Notes Page 9


Unit – III

cout << " Marks of Second student :";


Mark2.Display();

// use assignment operator


Mark1 = Mark2;

cout << " Mark in 1st Subject :";


Mark1.Display();

return 0;
}
Explanation
private:
int m1;
int m2;
Here, in Class Marks contains private Data Members m1 and m2.
Marks Mark1(45, 89);
Marks Mark2(36, 59);
In the main function, we have made two objects „Mark1‟ and „Mark2‟ of class „Marks‟. We have
initialized values of two objects using parametrised constructor.
void operator=(const Marks &M ) {
m1 = M.m1;
m2 = M.m2;
}
As shown in above code, we overload the assignment operator, Therefore, „Mark1=Mark2‟ from
main function will copy content of object „Mark2‟ into „Mark1‟.
Output
Marks of first student :
Mark in 1st Subject : 45
Marks in 2nd Subject : 89

Marks of Second student :


Mark in 1st Subject : 36
Marks in 2nd Subject : 59

Marks of First student :


Mark in 1st Subject : 36
Marks in 2nd Subject : 59

CPP Notes Page 10


Unit – III

Introduction to 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.

Access Control and Inheritance

A derived class can access all the non-private members of its base class. Thus base-class
members that should not be accessible to the member functions of derived classes should be
declared private in the base class.
We can summarize the different access types according to who can access them in the following
way:
Access public protected private

Same class yes yes yes

Derived classes yes yes no

Outside classes yes no no


A derived class inherits all base class methods with the following exceptions:
 Constructors, destructors and copy constructors of the base class.
 Overloaded operators of the base class.
 The friend functions of the base class.

CPP Notes Page 11


Unit – III

Reusability:
Object oriented technology allows reusability of the classes by extending them to other
classes using inheritance. Once a class is defined, the other programmer can also use it in their
programs. The programmer can also add new feature to the derived classes. The verified and
checked qualities of base classes need not to be redefined.

Types of inheritance:

a) Single Inheritance:
In this type of inheritance one derived class inherits from only one base class. It is
the most simplest form of Inheritance.

Ex:-
#include<iostream.h>
class ABC
{
protected:
char name[15];
int age;
};
class dc:public ABC
{
float height;
float weight;
public:
void getdata()
{
cout<<"\nEnter Name and Age:";
cin>>name>>age;

CPP Notes Page 12


Unit – III

cout<<"\nEnter height and weight:";


cin>>heigh>>weight;
}
void show()
{
cout<<"\nName:"<<name<<"\nAge:"<<age<<" Years";
cout<<"\nHeight:"<<height<<" Feets"<<"\n Weight:"<<weight<<"Kgs.";
}
};
int main()
{
clrscr();
dc x;
x.getdata();
x.show();
return 0;
}

Multiple Inheritance:
In this type of inheritance a single derived class may inherit from two or more than two
base classes.

Ex:-
#include<iostream>
using namespace std;
class A
{
protected:
int a;
};

CPP Notes Page 13


Unit – III

class B
{
protected:
int b;
};
class C:public A,public B
{
protected:
int c;
public:
void read()
{
cout<<"enter and b values";
cin>>a>>b;
}
void add()
{
c=a+b;
cout<<"c="<<c;
}
};
int main()
{
C obj;
obj.read();
obj.add();
}

Hierarchical Inheritance:
In this type of inheritance, multiple derived classes inherits from a single base class.

CPP Notes Page 14


Unit – III

Ex:-
#include<iostream>
using namespace std;
class A
{
protected:
int a,b;
public:
void read()
{
cout<<"enter a and b values";
cin>>a>>b;
}
};
class B:public A
{
protected:
int c;
public:
void add()
{
c=a+b;
cout<<"c="<<c;
}
};
class C:public A
{
protected:
int d;
public:
void sub()
{
d=a-b;
cout<<"d=\n"<<d;
}
};
class D:public A
{
protected:
int e;
public:
void mul()
{
CPP Notes Page 15
Unit – III

e=a*b;
cout<<"e=\n"<<e;
}
};
int main()
{
B obj;
obj.read();
obj.add();
C obj1;
obj1.read();
obj1.sub();
D obj2;
obj2.read();
obj2.mul();
return 0;
}

Multilevel Inheritance:
In this type of inheritance the derived class inherits from a class, which in turn inherits
from some other class. The Super class for one, is sub class for the other.

Ex:-
#include<iostream>
using namespace std;
class A
{
protected:
CPP Notes Page 16
Unit – III

int a;
};
class B:public A
{
protected:
int b;
};
class C:public B
{
protected:
int c;
public:
void read()
{
cout<<"enter a and b values";
cin>>a>>b;
}
void add()
{
c=a+b;
cout<<"c="<<c;
}
};
int main()
{
C obj;
obj.read();
obj.add();

Hybrid Inheritance:
A Combination of one or more types of inheritance is known as hybrid inheritance.

CPP Notes Page 17


Unit – III

Ex:-
#include<iostream>
using namespace std;
class A
{
protected:
int a;
};
class B:public A
{
protected:
int b;
};
class C
{
protected:
int c;
};
class D:public B,public C
{
protected:
int d;
public:
void read()
{
cout<<"enter a and b and c values";
cin>>a>>b>>c;
}
void mul()
{
d=(a*b*c);
cout<<"d="<<d;
}
};
int main()
{
D obj;
obj.read();
obj.mul();
}

CPP Notes Page 18


Unit – III

Virtual Base Classes:


To overcome the ambiguity occurring due to multipath inheritance, we need to use the
keyword virtual.
When classes are declared as virtual, the compiler takes essential caution to avoid the
duplication of member variables. Thus, we make a class virtual if it is a base class that has been
used by more than one derived class as their base class.
Ex:-
#include<iostream>
using namespace std;
class A
{
protected:
int a1;
};
class B: public virtual A
{
protected:
int a2;
};
class C: public virtual A
{
protected:
int a3;
};
class D :public B, public C
{
int a4;
public:
void input()
{
cout<<"Enter a1,a2,a3 and a4 values: ";
cin>> a1>>a2>>a3>>a4;
}
void show()
{
cout<<"a1="<<a1<<"\na2="<<a2;
cout<<"\na3="<<a3<<"\na4="<<a4;
}
};
int main()
{
D d;
d.input();

CPP Notes Page 19


Unit – III

d.show();
}

Object as a class Member:


Properties of one class can be used in another class using inheritance or using the objects
of a class as a member in another class. Declaring the object as a class data member in another
class is also known as delegation. When a class has an object of another class as its member,
such a class is known as a container class.
In delegation, the class consists of objects from other classes. The composed class uses
the properties of other classes through their objects. This kind of relationship is known as has-a
relationship.
Ex:-
class one
{
public:
int x;
one()
{
cout<<"\nConstructor of class one";
x=20;
}
};
class two
{
public:
int k;
one y;
two()
{
cout<<"\nConstructor of class two;
k=30;
}
void show()
{
cout<<"\nX="<<y.x<<" K="<<k;
}
};
int main()
{
two t;
t.show();
return 0;
}

CPP Notes Page 20


Unit – III

Abstract Classes:
When a class is not used for creating objects, it is called an abstract class. The abstract
class can act as a base class only. It is a layout abstraction in a program, and it allows a base on
which several levels of inheritance can be created. The base classes act as a foundation of the
hierarchical class. An abstract class is developed only to act as a base class and to inherit, and no
objects of this class are declared. An abstract class gives a skeleton or a structure; using this the
other classes are shaped.

Advantages and disadvantages of inheritance:


Advantages:

i. The most frequent use of inheritance is for deriving classes using existing classes, which
provides reusability. The existing classes remain unchanged. By reusability, the
development time of software is reduced.
ii. The derived classes extend the properties of base classes to generate more dominant
objects.
iii. The same base classes can be used by a number of derived classes in class hierarchy.
iv. When a class is derived from more than one class, all the derived classes have similar
properties to those of base classes.
Disadvantages:

i. Inappropriate use of inheritance makes programs more complicated.


ii. Invoking member functions using objects create more compiler overheads.
iii. In Class hierarchy, various data elements remain unchanged, and the memory allocated to
them is not utilized.

CPP Notes Page 21

You might also like