Unit 4 Lec Notes
Unit 4 Lec Notes
Operators Overloading
Where the return type is the type of value returned by the function.
operator op is an operator function where op is the operator being overloaded, and the
operator is the keyword.
o Existing operators can only be overloaded, but the new operators cannot be overloaded.
o The overloaded operator contains at least one operand of the user-defined data type.
o We cannot use friend function to overload certain operators. However, the member
function can be used to overload those operators. like = () [] ->.
o When unary operators are overloaded through a member function take no explicit
arguments, but, if they are overloaded by a friend function, takes one argument.
o When binary operators are overloaded through a member function takes one explicit
argument, and if they are overloaded through a friend function takes two explicit
arguments.
#include <iostream.h>
class Test
{
private:
int num;
public:
Test() {
num=8;
}
void operator ++() {
num = num+2;
}
void Print() {
cout<<"The Count is: "<<num;
}
};
int main()
{
Test tt;
++tt; // calling of a function "void operator ++()"
tt.Print();
return 0;
}
Output:
The Count is: 10
#include <iostream.h>
class Distance {
public:
// Member Object
int feet, inch;
// Constructor to initialize the object's value
Distance(int f, int i)
{
this->feet = f;
this->inch = i;
}
// Overloading(-) operator to perform decrement
// operation of Distance object
void operator-()
{
feet--;
inch--;
cout << "\nFeet & Inches(Decrement): " << feet << "'" << inch;
}
};
// Driver Code
int main()
{
// Declare and Initialize the constructor
Distance d1(8, 9);
// Use (-) unary operator by single operand
-d1;
return 0;
}
2. Overloading Binary Operator: In binary operator overloading function, there
should be one argument to be passed. It is overloading of an operator operating on
two operands.
#include <iostream.h>
class A
{
int x;
public:
A(){}
A(int i)
{
x=i;
}
void operator+(A);
void display();
};
void A :: operator+(A a)
{
int m = x+a.x;
cout<<"The result of the addition of two objects is : "<<m;
}
int main()
{
A a1(5);
A a2(4);
a1+a2;
return 0;
}
Output:
#include <iostream.h>
class Distance {
public:
// Member Object
int feet, inch;
// No Parameter Constructor
Distance()
{
this->feet = 0;
this->inch = 0;
}
// Constructor to initialize the object's value
// Parameterized Constructor
Distance(int f, int i)
{
this->feet = f;
this->inch = i;
}
// Overloading (+) operator to perform addition of
// two distance object
Distance operator+(Distance& d2) // Call by reference
{
// Create an object to return
Distance d3;
Syntax:
#include<iostream.h>
class UnaryFriend
{
int a=10;
int b=20;
int c=30;
public:
void getvalues()
{
cout<<"Values of A, B & C\n";
cout<<a<<"\n"<<b<<"\n"<<c<<"\n"<<endl;
}
void show()
{
cout<<a<<"\n"<<b<<"\n"<<c<<"\n"<<endl;
}
void friend operator-(UnaryFriend &x); //Pass by reference
};
void operator-(UnaryFriend &x)
{
x.a = -x.a; //Object name must be used as it is a friend function
x.b = -x.b;
x.c = -x.c;
}
int main()
{
UnaryFriend x1;
x1.getvalues();
cout<<"Before Overloading\n";
x1.show();
cout<<"After Overloading \n";
-x1;
x1.show();
return 0;
}
#include <iostream.h>
const int SIZE = 10;
class safearay {
private:
int arr[SIZE];
public:
safearay() {
int i;
for(i = 0; i < SIZE; i++) {
arr[i] = i;
}
}
int operator[](int i) {
if( i > SIZE ) {
cout << "Index out of bounds" <<endl;
// return first element.
return arr[0];
}
return arr[i];
}
};
int main() {
safearay A;
return 0;
}
Example : Write a C++ program to overload function call() operator .
#include <iostream.h>
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;
}
int main() {
Distance D1(11, 10), D2;
return 0;
}
Inheritance
In C++, inheritance is a process in which one object acquires all the properties and behaviors of its
parent object automatically. In such way, you can reuse, extend or modify the attributes and behaviors
which are defined in other class.
In C++, the class which inherits the members of another class is called derived class and the class
whose members are inherited is called base class. The derived class is the specialized class for the base
class.
Syntax:
// body of class
};
The base-class access specifier must be public, private or protected. If no access specifier is present,
the access specifier is private by default if the derived class is a class. In all cases, the base's private
elements remain private to the base and are not accessible by members of the derived class.
When the access specifier for a base class is public, all public members of the base become public
members of the derived class, and all protected members of the base become protected members of the
derived class.
When the base class is inherited by using the private access specifier, all public and protected
members of the base class become private members of the derived class.
When a base class' access specifier is protected, public and protected members of the base become
protected members of the derived class.
Advantage of Inheritance
Code reusability: Now you can reuse the members of your parent class. So, there is no need to define
the member again. So less code is required in the class.
Types Of Inheritance : C++ supports five types of inheritance:
o Single inheritance
o Multilevel inheritance
o Multiple inheritance
o Hierarchical inheritance
o Hybrid inheritance
1. Single Inheritance
Single inheritance is defined as the inheritance in which a derived class is inherited from the only one
base class.
Where 'A' is the base class, and 'B' is the derived class.
Example:1
#include <iostream.h>
class Account {
public:
float salary = 60000;
};
class Programmer : public Account {
public:
float bonus = 5000;
};
int main(void) {
Programmer p1;
cout<<"Salary: "<<p1.salary<<endl;
cout<<"Bonus: "<<p1.bonus<<endl;
return 0;
}
Output:
Salary: 60000
Bonus: 5000
Example:2
#include <iostream.h>
class Animal {
public:
void eat() {
cout<<"Eating..."<<endl;
}
};
class Dog: public Animal
{
public:
void bark(){
cout<<"Barking...";
}
};
int main(void) {
Dog d1;
d1.eat();
d1.bark();
return 0;
}
Output:
Eating...
Barking...
Example:3
#include <iostream.h>
class A
{
int a = 4;
int b = 5;
public:
int mul()
{
int c = a*b;
return c;
}
};
class B : private A{
public:
void display()
{
int result = mul();
std::cout <<"Multiplication of a and b is : "<<result<< std::endl;
}};
int main()
{
B b;
b.display();
return 0;
}
Output:
Multiplication of a and b is : 20
In the above example, class A is privately inherited. Therefore, the mul() function of class 'A' cannot
be accessed by the object of class B. It can only be accessed by the member function of class B.
The private member is not inheritable. If we modify the visibility mode by making it public, but this
takes away the advantage of data hiding.
C++ introduces a third visibility modifier, i.e., protected. The member which is declared as protected
will be accessible to all the member functions within the class as well as the class immediately derived
from it.
Visibility modes can be classified into three categories:
o Public: When the member is declared as public, it is accessible to all the functions of the
program.
o Private: When the member is declared as private, it is accessible within the class only.
o Protected: When the member is declared as protected, it is accessible within its own class as
well as the class immediately derived from it.
2. Multilevel Inheritance
Example:
#include <iostream.h>
class Animal {
public:
void eat() {
cout<<"Eating..."<<endl;
}
};
class Dog: public Animal
{
public:
void bark(){
cout<<"Barking..."<<endl;
}
};
class BabyDog: public Dog
{
public:
void weep() {
cout<<"Weeping...";
}
};
int main(void) {
BabyDog d1;
d1.eat();
d1.bark();
d1.weep();
return 0;
}
Output:
Eating...
Barking...
Weeping...
3. Multiple Inheritance
Multiple inheritance is the process of deriving a new class that inherits the attributes from two or
more classes.
{
// Body of the class;
}
Example:
#include <iostream.h>
class A
{
protected:
int a;
public:
void get_a(int n)
{
a = n;
} };
class B
{
protected:
int b;
public:
void get_b(int n)
{
b = n;
}
};
class C : public A, public B
{
public:
void display()
{
cout << "The value of a is : " <<a<< endl;
cout << "The value of b is : " <<b<< endl;
cout<<"Addition of a and b is : "<<a+b;
}
};
int main()
{
C c;
c.get_a(10);
c.get_b(20);
c.display();
return 0;
}
Output:
The value of a is : 10
The value of b is : 20
Addition of a and b is : 30
In the above example, class 'C' inherits two base classes 'A' and 'B' in a public mode.
Ambiguity can be occurred in using the multiple inheritance when a function with the same name
occurs in more than one base class. Let's understand this through an example:
#include <iostream.h>
class A
{
public:
void display()
{
cout << "Class A" << endl;
} };
class B
{
public:
void display()
{
cout << "Class B" << endl;
} };
class C : public A, public B
{
void view()
{
display();
} };
int main()
{
C c;
c.display();
return 0;
}
Output:
} };
An ambiguity can also occur in single inheritance. Consider the following situation:
class A
{
public:
void display()
{
cout<<”Class A”;
}
};
class B
{
public:
void display()
{
cout<<”Class B”;
} };
In the above case, the function of the derived class overrides the method of the base class. Therefore,
call to the display() function will simply call the function defined in the derived class. If we want to
invoke the base class function, we can use the class resolution operator.
int main()
{
B b;
b.display(); // Calling the display() function of B class.
b.B :: display(); // Calling the display() function defined in B class.
}
4. Hybrid Inheritance
Hybrid inheritance is a combination of more than one type of inheritance.
Example:
#include <iostream.h>
class A
{
protected:
int a;
public:
void get_a()
{
cout << "Enter the value of 'a' : " << endl;
cin>>a;
} };
class B : public A
{
protected:
int b;
public:
void get_b()
{
cout << "Enter the value of 'b' : " << endl;
cin>>b;
}
};
class C
{
protected:
int c;
public:
void get_c()
{
cout << "Enter the value of c is : " << endl;
cin>>c;
}
};
Output:
5. Hierarchical Inheritance
Hierarchical inheritance is defined as the process of deriving more than one class from a base class.
class A
{
// body of the class A.
}
class B : public A
{
// body of class B.
}
class C : public A
{
// body of class C.
}
class D : public A
{
// body of class D.
}
Example:
#include <iostream.h>
class Shape // Declaration of base class.
{
public:
int a;
int b;
void get_data(int n,int m)
{
a= n;
b = m;
}
};
class Rectangle : public Shape // inheriting Shape class
{
public:
int rect_area()
{
int result = a*b;
return result;
}
};
class Triangle : public Shape // inheriting Shape class
{
public:
int triangle_area()
{
float result = 0.5*a*b;
return result;
}
};
int main()
{
Rectangle r;
Triangle t;
int length,breadth,base,height;
cout << "Enter the length and breadth of a rectangle: " << endl;
cin>>length>>breadth;
r.get_data(length,breadth);
int m = r.rect_area();
cout << "Area of the rectangle is : " <<m<< endl;
cout << "Enter the base and height of the triangle: " << endl;
cin>>base>>height;
t.get_data(base,height);
float n = t.triangle_area();
cout <<"Area of the triangle is : " << n<< endl;
return 0;
}
Output:
#include <iostream.h>
class base
{
public:
base()
{
cout << "Constructing base\n";
}
~base()
{
cout << "Destructing base\n";
}};
class derived: public base
{
public:
derived(){
cout << "Constructing derived\n";
}
~derived(){
cout << "Destructing derived\n";
}};
void main(){
derived ob;
} Output:
Constructing base
Constructing derived
Destructing derived
Destructing base
Note:In the above program, first base's constructor is executed followed by derived's. Next (because
obis immediately destroyed in this program), derived’s destructor is called, followed by base's.
Example 2: Constructor and Destructor execution in multilevel inheritance
#include <iostream.h>
class base
{
public:
base()
{
cout << "Constructing base\n";
}
~base()
{
cout << "Destructing base\n";
}};
class derived1 : public base{
public:
derived1()
{
cout << "Constructing derived1\n";
}
~derived1(){
cout << "Destructing derived1\n";
}};
class derived2: public derived1
{
public:
derived2()
{
cout << "Constructing derived2\n";
}
~derived2(){
cout << "Destructing derived2\n";
}};
void main()
{
derived2 ob;
}
Output:
Constructing base Constructing
derived1Constructing
derived2 Destructing
derived2Destructing
derived1Destructing base.
Example 3: Constructor and Destructor execution in multiple inheritance
#include <iostream.h>
class base1
{
public:
base1()
{
cout << "Constructing base1\n";
}
~base1(){
cout << "Destructing base1\n";
}};
class base2
{
public:
base2()
{
cout<< "Constructing base2\n";
}
~base2()
{
cout << "Destructing base2\n";
}};
class derived: public base1, public base2
{
public:
derived()
{
cout << "Constructing derived\n";
}
~derived(){
cout << "Destructing derived\n";
}};
void main()
{
derived ob;
}
Output:
Constructing base1
Constructing base2
Constructing derived
Destructing derived
Destructing base2
Destructing base1
Note: In the above program, constructors are called in order of derivation, left to right, as specified in
derived's inheritance list. Destructors are called in reverse order, right to left.
Output:
Multipath inheritance
Multipath inheritance in C++ is derivation of a class from other derived classes, which are derived
from the same base class. In this type of inheritance, there involves other inheritance like
multiple, multilevel, hierarchical etc.
Multipath inheritance
Here, class D is derived from derived classes B & C directly and from class A indirectly.
(hierarchical and multiple)
Both derived classes inherits the features of base class. Hence when we derive a new class
by inheriting features form these two classes derived from the same base class, then
same features from the first base is inherited to the finally derived class from two paths.
This cause ambiguity in accessing first base class members.
To eliminate this problem, C++ has a mechanism to inherit a single copy of properties
from the common base class.
This is done by declaring the base class as virtual while creating derive classes from this
base class.
Virtual base classes are used in virtual inheritance in a way of preventing multiple “instances” of a
given class appearing in an inheritance hierarchy when using multiple inheritances.
As we can see from the figure that data members/function of class A are inherited twice to class D.
One through class B and second through class C. When any data / function member of class A is
accessed by an object of class D, ambiguity arises as to which data/function member would be
called? One inherited through B or the other inherited through C. This confuses compiler and it
displays error.
#include<iostream.h> int main() {
class A { D obj;
public: int b; obj.b = 40; // statement 3
}; obj.b = 30; // statement 4
class B : virtual public A { obj.d1 = 60;
public: int d1; obj.d2 = 70;
}; obj.d3 = 80;
class C: virtual public A { cout<< "\n A : "<< obj.b;
public: int d2; cout<< "\n B : "<< obj.d1;
}; cout<< "\n C : "<< obj.d2;
class D : public B, public C { cout<< "\n D : "<< obj.d3;
public: int d3; }
};
Function Overriding
If derived class defines same function as defined in its base class, it is known as function overriding in
C++. It is used to achieve runtime polymorphism. It enables you to provide specific implementation of
the function which is already provided by its base class.