0% found this document useful (0 votes)
6 views

OOP'S _ Module -II_(Polymorphism)Notes

The document explains polymorphism in programming, particularly in C++, highlighting its types: compile-time and runtime polymorphism. It details function overloading and operator overloading for compile-time polymorphism, and function overriding and virtual functions for runtime polymorphism. Additionally, it covers exception handling, file handling, and the differences between unary and binary operators.

Uploaded by

kshitijasingh24
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

OOP'S _ Module -II_(Polymorphism)Notes

The document explains polymorphism in programming, particularly in C++, highlighting its types: compile-time and runtime polymorphism. It details function overloading and operator overloading for compile-time polymorphism, and function overriding and virtual functions for runtime polymorphism. Additionally, it covers exception handling, file handling, and the differences between unary and binary operators.

Uploaded by

kshitijasingh24
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

Module-II

Polymorphism:

The word “polymorphism” means having many forms. In simple words, we can define
polymorphism as the ability of a message to be displayed in more than one form.
A real-life example of polymorphism is a person who at the same time can have different
characteristics.
A man at the same time is a father, a husband, and an employee. So the same person
exhibits different behaviour in different situations.
This is called polymorphism. Polymorphism is considered one of the important features of
Object-Oriented Programming.

Types of Polymorphism
 Compile-time Polymorphism
 Runtime Polymorphism

1. Compile-Time Polymorphism
This type of polymorphism is achieved by function overloading or operator overloading.

A. Function Overloading
When there are multiple functions with the same name but different parameters, then the
functions are said to be overloaded, hence this is known as Function Overloading.

Functions can be overloaded by changing the number of arguments or/and changing the
type of arguments. In simple terms, it is a feature of object-oriented programming
providing many functions that have the same name but distinct parameters when numerous
tasks are listed under one function name.
There are certain Rules of Function Overloading that should be followed while overloading
a function.
Below is the C++ program to show function overloading or compile-time polymorphism:

// C++ program to demonstrate


// function overloading or
// Compile-time Polymorphism
#include <bits/stdc++.h>

using namespace std;


class Geeks {
public:
// Function with 1 int parameter
void func(int x)
{
cout << "value of x is " << x << endl;
}

// Function with same name but


// 1 double parameter
void func(double x)
{
cout << "value of x is " << x << endl;
}

// Function with same name and


// 2 int parameters
void func(int x, int y)
{
cout << "value of x and y is " << x << ", " << y
<< endl;
}
};

// Driver code
int main()
{
Geeks obj1;

// Function being called depends


// on the parameters passed
// func() is called with int value
obj1.func(7);

// func() is called with double value


obj1.func(9.132);

// func() is called with 2 int values


obj1.func(85, 64);
return 0;
}
Output

value of x is 7
value of x is 9.132
value of x and y is 85, 64

B. Operator Overloading
C++ has the ability to provide the operators with a special meaning for a data type, this
ability is known as operator overloading. For example, we can make use of the addition
operator (+) for string class to concatenate two strings. We know that the task of this
operator is to add two operands. So a single operator ‘+’, when placed between integer
operands, adds them and when placed between string operands, concatenates them.
Below is the C++ program to demonstrate operator overloading:
// C++ program to demonstrate
// Operator Overloading or
// Compile-Time Polymorphism
#include <iostream>
using namespace std;

class Complex {
private:
int real, imag;

public:
Complex(int r = 0, int i = 0)
{
real = r;
imag = i;
}

// This is automatically called


// when '+' is used with between
// two Complex objects
Complex operator+(Complex const& obj)
{
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + i" << imag << endl; }
};

// Driver code
int main()
{
Complex c1(10, 5), c2(2, 4);

// An example call to "operator+"


Complex c3 = c1 + c2;
c3.print();
}

Output

12 + i9

2. Runtime Polymorphism

This type of polymorphism is achieved by Function Overriding. Late binding and


dynamic polymorphism are other names for runtime polymorphism.
The function call is resolved at runtime in runtime polymorphism .
In contrast, with compile time polymorphism, the compiler determines which function call
to bind to the object after deducing it at runtime.

A. Function Overriding
Function Overriding occurs when a derived class has a definition for one of the member
functions of the base class.
That base function is said to be overridden.
Function overriding Explanation

Runtime Polymorphism with Data Members


Runtime Polymorphism cannot be achieved by data members in C++.
Let’s see an example where we are accessing the field by reference variable of parent class
which refers to the instance of the derived class.
// C++ program for function overriding with data members
#include <bits/stdc++.h>
using namespace std;

// base class declaration.


class Animal {
public:
string color = "Black";
};

// inheriting Animal class.


class Dog : public Animal {
public:
string color = "Grey";
};

// Driver code
int main(void)
{
Animal d = Dog(); // accessing the field by reference
// variable which refers to derived
cout << d.color;
}

Output

Black
We can see that the parent class reference will always refer to the data member of the
parent class.

B. Virtual Function
A virtual function is a member function that is declared in the base class using the keyword
virtual and is re-defined (Overridden) in the derived class.

Some Key Points About Virtual Functions:


 Virtual functions are Dynamic in nature.
 They are defined by inserting the keyword “virtual” inside a base class and are always
declared with a base class and overridden in a child class
 A virtual function is called during Runtime

Below is the C++ program to demonstrate virtual function:

// C++ Program to demonstrate


// the Virtual Function
#include <iostream>
using namespace std;

// Declaring a Base class


class GFG_Base {

public:
// virtual function
virtual void display()
{
cout << "Called virtual Base Class function"
<< "\n\n";
}

void print()
{
cout << "Called GFG_Base print function"
<< "\n\n";
}
};

// Declaring a Child Class


class GFG_Child : public GFG_Base {

public:
void display()
{
cout << "Called GFG_Child Display Function"
<< "\n\n";
}

void print()
{
cout << "Called GFG_Child print Function"
<< "\n\n";
}
};

int main()
{
// Create a reference of class GFG_Base
GFG_Base* base;

GFG_Child child;

base = &child;

// This will call the virtual function


base->display();

// This will call the non-virtual function


base->print();
}
Output

Called GFG_Child Display Function

Called GFG_Base print function

A virtual function (also known as virtual methods) is a member function that is declared
within a base class and is re-defined (overridden) by a derived class.
When you refer to a derived class object using a pointer or a reference to the base class, you
can call a virtual function for that object and execute the derived class’s version of the
method.

 Virtual functions ensure that the correct function is called for an object, regardless of
the type of reference (or pointer) used for the function call.
 They are mainly used to achieve Runtime polymorphism .
 Functions are declared with a virtual keyword in a base class.
 The resolving of a function call is done at runtime.

Rules for Virtual Functions

The rules for the virtual functions in C++ are as follows:


1. Virtual functions cannot be static.
2. A virtual function can be a friend function of another class.
3. Virtual functions should be accessed using a pointer or reference of base class type to
achieve runtime polymorphism.
4. The prototype of virtual functions should be the same in the base as well as the derived
class.
5. They are always defined in the base class and overridden in a derived class. It is not
mandatory for the derived class to override (or re-define the virtual function), in that
case, the base class version of the function is used.
6. A class may have a virtual destructor but it cannot have a virtual constructor.

Compile time (early binding) VS runtime (late binding) behavior of Virtual Functions
Consider the following simple program showing the runtime behavior of virtual functions.

// C++ program to illustrate


// concept of Virtual Functions

#include <iostream>
using namespace std;

class base {
public:
virtual void print() { cout << "print base class\n"; }

void show() { cout << "show base class\n"; }


};

class derived : public base {


public:
void print() { cout << "print derived class\n"; }

void show() { cout << "show derived class\n"; }


};

int main()
{
base* bptr;
derived d;
bptr = &d;

// Virtual function, binded at runtime


bptr->print();

// Non-virtual function, binded at compile time


bptr->show();

return 0;
}

Output

print derived class


show base class
Operators

Unary Operators and Binary operators are both fundamental


concepts in computer science and programming languages, especially
in the context of arithmetic and logical operations. Here's a breakdown
of the differences between them:

Unary Operators:
Unary Operator is an operator that operates on a single operand,
meaning it affects only one value or variable.
Unary operators are commonly used in programming languages to
perform various operations such as changing the sign of a value,
incrementing or decrementing a value, or performing logical negation.

Examples of Unary Operators:


Here are the examples of Unary Operator in Programming:
 Unary minus (-x)
 Increment (++)
 Decrement (--)
 Logical NOT (!x)

Binary Operators:
Binary Operator is an operator that operates on two operands,
meaning it affects two values or variables.
Binary operators are commonly used in programming languages to
perform various operations such as arithmetic operations, logical
operations, and bitwise operations.

Examples of Binary Operators:


Here are the examples of Binary operator in Programming:
 Addition (+)
 Subtraction (-)
 Multiplication (*)
 Division (/)
 Assignment (=)
 Logical AND (&&)
 Logical OR (||)
Difference between Unary and Binary Operators:
Aspect Unary Operators Binary Operators

Number of
Operates on one operand Operates on two operands
Operands

Example -x, ++i, !flag x + y, a * b, value == 10

Typically perform
Perform operations
operations on a single
involving two values
Operations value

Syntax and May appear before or after Appears between the


Usage the operand operands

Used for arithmetic


Used for operations like
operations, comparisons,
negation, increment, etc.
Purpose etc.

Some have prefix and Usually left-associative ( a +


Associativity postfix forms (++i, i++) b + c)

Exception Handling in C++

In C++, exceptions are runtime anomalies or abnormal conditions that a program


encounters during its execution.
The process of handling these exceptions is called exception handling.
Using the exception handling mechanism, the control from one part of the program where
the exception occurred can be transferred to another part of the code.
So basically using exception handling in C++, we can handle the exceptions so that our
program keeps running.

What is a C++ Exception?


An exception is an unexpected problem that arises during the execution of a program our
program terminates suddenly with some errors/issues.
Exception occurs during the running of the program (runtime).

Types of C++ Exception


There are two types of exceptions in C++

1. Synchronous: Exceptions that happen when something goes wrong because of a


mistake in the input data or when the program is not equipped to handle the current type
of data it’s working with, such as dividing a number by zero.
2. Asynchronous: Exceptions that are beyond the program’s control, such as disc failure,
keyboard interrupts, etc.

C++ try and catch

C++ provides an inbuilt feature for Exception Handling. It can be done using the following
specialized keywords: try, catch, and throw with each having a different purpose.
Syntax of try-catch in C++

try {
// Code that might throw an exception
throw SomeExceptionType("Error message");
}
catch( ExceptionName e1 ) {
// catch block catches the exception that is thrown from try block
}

1. try in C++
The try keyword represents a block of code that may throw an exception placed inside the
try block. It’s followed by one or more catch blocks. If an exception occurs, try block
throws that exception.

2. catch in C++
The catch statement represents a block of code that is executed when a particular exception
is thrown from the try block. The code to handle the exception is written inside the catch
block.
3. throw in C++
An exception in C++ can be thrown using the throw keyword. When a program encounters
a throw statement, then it immediately terminates the current function and starts finding a
matching catch block to handle the thrown exception.

Note: Multiple catch statements can be used to catch different type of exceptions thrown by
try block.
The try and catch keywords come in pairs: We use the try block to test some code and If the
code throws an exception we will handle it in our catch block.

Why do we need Exception Handling in C++?


The following are the main advantages of exception handling over traditional error
handling:

1. Separation of Error Handling Code from Normal Code: There are always if-else
conditions to handle errors in traditional error handling codes.
2. These conditions and the code to handle errors get mixed up with the normal flow. This
makes the code less readable and maintainable.
3. With try/catch blocks, the code for error handling becomes separate from the normal
flow.

2. Functions/Methods can handle only the exceptions they choose: A function can
throw many exceptions, but may choose to handle some of them.
3. The other exceptions, which are thrown but not caught, can be handled by the caller. If
the caller chooses not to catch them, then the exceptions are handled by the caller of the
caller.
In C++, a function can specify the exceptions that it throws using the throw keyword.
The caller of this function must handle the exception in some way (either by specifying
it again or catching it).

3. Grouping of Error Types: In C++, both basic types and objects can be thrown as
exceptions. We can create a hierarchy of exception objects, group exceptions in
namespaces or classes, and categorize them according to their types.

Examples of Exception Handling in C++


The following examples demonstrate how to use a try-catch block to handle exceptions in
C++.

Example 1
The below example demonstrates throw exceptions in C++.

// C++ program to demonstate the use of try,catch and throw


// in exception handling.

#include <iostream>
#include <stdexcept>
using namespace std;

int main()
{

// try block
try {
int numerator = 10;
int denominator = 0;
int res;

// check if denominator is 0 then throw runtime


// error.
if (denominator == 0) {
throw runtime_error(
"Division by zero not allowed!");
}

// calculate result if no exception occurs


res = numerator / denominator;
//[printing result after division
cout << "Result after division: " << res << endl;
}
// catch block to catch the thrown exception
catch (const exception& e) {
// print the exception
cout << "Exception " << e.what() << endl;
}

return 0;
}

Output

Exception Division by zero not allowed!

Limitations of Exception Handling in C++

The exception handling in C++ also have few limitations:

 Exceptions may break the structure or flow of the code as multiple invisible exit points
are created in the code which makes the code hard to read and debug.
 If exception handling is not done properly can lead to resource leaks as well.
 It’s hard to learn how to write Exception code that is safe.
 There is no C++ standard on how to use exception handling, hence many variations in
exception-handling practices exist.

File handling
File handling is used to store data permanently in a computer.
Using file handling we can store our data in secondary memory (Hard disk).
How to achieve the File Handling
For achieving file handling we need to follow the following steps:-
STEP 1-Naming a file
STEP 2-Opening a file
STEP 3-Writing data into the file
STEP 4-Reading data from the file
STEP 5-Closing a file.

Streams in C++ :-
We give input to the executing program and the execution program gives back the output.
The sequence of bytes given as input to the executing program and the sequence of bytes
that comes as output from the executing program are called stream.
In other words, streams are nothing but the flow of data in a sequence.
The input and output operation between the executing program and the devices like
keyboard and monitor are known as “console I/O operation”.
The input and output operation between the executing program and files are known as “disk
I/O operation”.

Classes for File stream operations :-


The I/O system of C++ contains a set of classes which define the file handling methods.
These include ifstream, ofstream and fstream classes.
These classes are derived from fstream and from the corresponding iostream class.
These classes, designed to manage the disk files, are declared in fstream and therefore we
must include this file in any program that uses files. File handling is essential for data
storage and retrieval in applications.

1. ios:-
 ios stands for input output stream.
 This class is the base class for other classes in this class hierarchy.
 This class contains the necessary facilities that are used by all the other derived classes
for input and output operations.

2. istream:-
 istream stands for input stream.
 This class is derived from the class ‘ios’.
 This class handle input stream.
 The extraction operator(>>) is overloaded in this class to handle input streams from
files to the program execution.
 This class declares input functions such as get(), getline() and read().

3. ostream:-
 ostream stands for output stream.
 This class is derived from the class ‘ios’.
 This class handle output stream.
 The insertion operator(<<) is overloaded in this class to handle output streams to files
from the program execution.
 This class declares output functions such as put() and write().
4. streambuf:-
 This class contains a pointer which points to the buffer which is used to manage the
input and output streams.
5. fstreambase:-
 This class provides operations common to the file streams. Serves as a base for fstream,
ifstream and ofstream class.

 This class contains open() and close() function.


6. ifstream:-
 This class provides input operations.
 It contains open() function with default input mode.
 Inherits the functions get(), getline(), read(), seekg() and tellg() functions from the
istream.
7. ofstream:-
 This class provides output operations.
 It contains open() function with default output mode.
 Inherits the functions put(), write(), seekp() and tellp() functions from the ostream.
8. fstream:-
 This class provides support for simultaneous input and output operations.
 Inherits all the functions from istream and ostream classes through iostream.
9. filebuf:-
 Its purpose is to set the file buffers to read and write.
 We can also use file buffer member function to determine the length of the file.

In C++, files are mainly dealt by using three classes fstream, ifstream, ofstream available in
fstream headerfile.

ofstream: Stream class to write on files


ifstream: Stream class to read from files
fstream: Stream class to both read and write from/to files.

Difference:
r mode r+ mode

Opens an existing text file Opens a text file for both


Purpose
for reading purpose. reading and writing.

fopen Returns if
NULL Create New File
FILE doesn’t exists

fopen returns if FILE Returns a pointer to the New data is written at the
exist FILE object. start of existing data

file pointer position at the first char of the file at the first char of the file

You might also like