Notes_CSE2001_OOP_with_C++_Unit III
Notes_CSE2001_OOP_with_C++_Unit III
UNIT – III
Syllabus:
Learning Objectives: To
1. Polymorphism:
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Similarly in programming world also, we can have an operator “+” that is the
binary addition operator which behaves differently when the operands change.
For Example, when both the operands are numeric, it performs addition.
On the other hand, when the operands are string, it acts as concatenation
operator. Thus polymorphism, in a nutshell, means an entity taking up many
forms or behaving differently under different conditions.
Types of Polymorphism
Let us see the main differences between compile time and runtime
polymorphism below.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Compile time polymorphism Runtime polymorphism
Objects method is invoked at compile time Object’s method is invoked at run time
Since methods are known at compile time, Execution is slower since the method is
execution is faster known at runtime
o Function overloading
o Operator overloading
Function Overloading
A function is said to be overloaded when we have more than one function with the same
name but different parameter types or a different number of arguments.
Thus a function can be overloaded based on the parameter types, the order of
parameters and the number of parameters.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Note that two functions having the same name and same parameter list but different
return type is not an overloaded function and will result in a compilation error if used in
the program.
Similarly, when function parameters differ only in pointer and if array type is
equivalent, then it should not be used for overloading.
Other types like static and non-static, const and volatile, etc. Or parameter declarations
that differ in presence or absence of default values are also not to be used for
overloading as they are equivalent from the implementation point of view.
o Add(int,int);
o Add(int,float);
o Add(float,int);
o Add(int,int,int);
In the above program, we have a Summation class that defined three overloaded
functions named Add which takes two integer arguments, three integer arguments, and
two string arguments.
In the main function, we make four function calls that provide various parameters. The
first two function calls are straightforward. In the third function call to Add, we provide
two floating point values as arguments.
In this case, the function that is matched is int Add (int, int) as internally, the float is
converted to double and then matched with the function with the int parameters. If we
had specified double instead of float, then we would have another overloaded function
with double as parameters.
The last function call uses string values as parameters. In this case, the Add (+) operator
acts as a concatenation operator and concatenates the two string values to produce a
single string.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Operator Overloading
Operator overloading is the technique using which we give a different meaning to the
existing operators in C++. In other words, we overload the operators to give a special
meaning to the user-defined data types as objects.
Most of the operators in C++ are overloaded or given special meaning so that they can
work on user-defined data types. Note that while overloading, the basic operation of
operators is not altered. Overloading just gives the operator an additional meaning by
keeping their basic semantic same.
Though most of the operators can be overloaded in C++, there are some operators
which cannot be overloaded.
The functions that we use to overload operators are called “Operator functions”.
Operator functions are similar to the normal functions but with a difference. The
difference is that the name of the operator functions begins with the keyword
“operator” followed by the operator symbol that is to be overloaded.
The operator function is then called when the corresponding operator is used in the
program. These operator functions can be the member functions or global methods or
even a friend function.
The only difference in the implementation is the use of friend function to overload the +
operator instead of a member function in the previous example.
o When friend function is used for a binary operator, we have to explicitly specify
both the operands to the function. Similarly, when the unary operator is
overloaded using friend function, we need to provide the single operand to the
function.
While performing operator overloading, we need to watch out the below rules.
o In C++, we are able to overload the existing operators only. Newly added
operators cannot be overloaded.
o When operators are overloaded, we need to ensure that at least one of the
operands is of the user-defined type.
o To overload certain operators, we can make use of friend function as well.
o When we overload unary operators using a member function, it doesn’t take any
explicit arguments. It takes one explicit argument when the unary operator is
overloaded using friend function.
o Similarly, when binary operators are overloaded using member function, we
have to provide one explicit argument to the function. When binary operators
are overloaded using friend function, the function takes two arguments.
o There are two operators in C++ that are already overloaded. These are “=” and
“&”. Therefore to copy an object of the same class, we need not overload the =
operator, and we can use it directly.
By extending the operator functionality to the user-defined types, we need not write
complex code to perform various operations on user-defined types but, we can do it in
one operation itself just like the built-in types.
Conclusion
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
o Operator overloading, can extend the functionality of operators, so that we can
do basic operations on user-defined types as well.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Runtime Polymorphism
2. Inheritance
Inheritance is the process by which objects of one class can acquire the properties,
functions, and data of objects of another class. It follows the concept of hierarchical
classification. For example, the bird ‘sparrow’ is a part of the class ‘flying bird’ which is
again a part of the class ‘bird’. With the help of this sort of division each derived class
shares common characteristics and data with the class from which it is inherited.
Inheritance provides the idea of reusability. This means that we can add additional
features to an existing class without modifying or making any changes in it. This is
possible by deriving a new class from the existing class. The new class will acquire the
combined features of both parent and child class.
The real use of the inheritance is that it allows the programmer to reuse a class that is
almost, but not exactly, what he wants, and to alter the class and make changes in such a
way that it does not introduce any undesirable side-effects into the rest of the classes.
Note that each sub-class defines only those features that are unique to it and the rest of
it, it derives from its parent class. Without the use of any classification, each class would
have to explicitly include all of its features which would have taken a lot of time and
effort.
Inheritance is one of the most powerful and widely used concepts in C++ or any other
Object-oriented language. Understanding this concept requires a little knowledge of
classes and objects. Using Inheritance, we can create a class that consists of general
methods and attributes. This class can be inherited by other classes containing more
specific methods.
By doing this we don’t have to write the same functionalities again and again which
saves time and increases the readability of code.
Syntax:
class derived_class: access_type base_class
{
// class body
};
Base class: The class which consists of all the general methods and attributes which can
be shared by other classes to increase code readability is called a base class.
Derived class: The class which consists of more specific methods and inherits a class is
called a derived class. A derived class can also be a base class for some other derived
class.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
If we create a class XYZ (College), with some attributes and methods. Now a class
student will have some other attributes, but it will also include the elements of XYZ class
and the same goes for a faculty class. Let’s see a diagram:
So, the student and faculty class will inherit from XYZ.
Access specifier - We understood how a class can inherit another class. But some
people might say that it is an unsafe method as all the attributes and methods of the
base class or the parent class is shared with the child class or the derived class. For
example, if a class ‘Bank’ is inherited by the class ‘customers’ and ‘investors’. Attributes
of class ‘Bank’ such as ‘vaultpassword’, other customer-related information and private
data is shared with the ‘customers’ and the ‘investors’ class which is unsafe.
To solve the above problem C++ uses access specifiers to limit the access of base class
attributes to the derived class. There are a total of 3 types of access specifiers in C++
• Public
• Private
• Protected
The below table will give you a good understanding of what type of data can be accessed
by derived class according to different access specifiers.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Types of Inheritance:
1. Single Inheritance
In Single inheritance, class is derived from only one base class.
Syntax:
class base {
//…
};
class derived: [access_to_base] base {
//….
}
2. Multiple Inheritance
A class is derived from two or more base class.
Syntax:
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Example:
class B1
{
//…
};
class B2
{
//…
};
class D: public B1, protected B2
{
//..
};
3. Multilevel inheritance
The derivation of a class from another derived class is called multilevel inheritance.
A new class that is derived from the base class serves as a base for further inheritance.
In case of second derivation, the members inherited as protected or public form first
inheritance can be visible from the second derived class.
class A
{
//…
};
class B : public A
{
//…
};
class C: public B
{
//..
};
4. Hierarchical inheritance
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
class derived: [access_to_base] base {
//…
};
class derived2:[access_to_base] base {
//…
};
.
class derivedn:[ access_to_base] base {
//…
}
• Base class constructors are called first and the derived class constructors are called
next in single inheritance.
Here, Base is inherited first, so the constructor of class Base is called first and then
constructor of class Derived is called next.
However, the destructor of derived class is called first and then destructor of the base
class which is mentioned in the derived class declaration is called from last towards first
in sequentially.
• Constructors from all base class are invoked first and the derived class constructor is
called.
• Order of constructor invocation depends on the order of how the base is inherited.
• For example:
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Here, B is inherited first, so the constructor of class B is called first and then constructor
of class C is called next.
• However, the destructor of derived class is called first and then destructor of the base
class which is mentioned in the derived class declaration is called from last towards first
in sequentially.
To further understand the ambiguity that arise due to multiple instances / objects
(constructors and destructors) in inheritance. Refer the program and figure below:
# The classes Cyber and Gaming derived from CSE. Class AIML derived from: Cyber,
Gaming, and CSE. Consider the inheritance access is public. Then instantiate the object of
AIML.
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.
Consider the situation where we have one class A .This class is A is inherited by two
other classes B and C. Both these class are inherited into another in a new class D as
shown in figure below.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
{
cout<<"A class destructor"<<endl;
} Output: with virtual keyword
};
class B : virtual public A
{ A class constructor
public: B class constructor
B() C class constructor
{ D class constructor
cout<<"B class constructor"<<endl; D class destructor
} C class destructor
~B() B class destructor
{ A class destructor
cout<<"B class destructor"<<endl;
}
};
class C: virtual public A
{
public: Note: Using the keyword virtual
C() before derivation type enables virtual
{ inheritance for class D.
cout<<"C class constructor"<<endl;
}
~C()
{
cout<<"C class destructor"<<endl;
}
};
class D:public B, public C
{
public:
D()
{
cout<<"D class
constructor"<<endl;
}
~D()
{
cout<<"D class destructor"<<endl;
}
};
int main()
{
D d;
return 0;
}
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
In C++, we use terms abstract class and interface interchangeably. A class with pure
virtual function is known as abstract class. Or the class which has at least one pure
virtual function that is called an “abstract class”. We can never instantiate the abstract
class i.e. we cannot create an object of the abstract class.
o A pure virtual function is marked with a virtual keyword and has = 0 after its
signature.
o You can call this function an abstract function as it has no body.
o The derived class must give the implementation to all the pure virtual functions
of parent class else it will become abstract class by default.
Let’s understand this with the help of a real life example. Lets say we have a class
Animal, animal sleeps, animal make sound, etc. For now I am considering only these two
behaviours and creating a class Animal with two functions sound() and sleeping().
Now, we know that animal sounds are different cat says “meow”, dog says “woof”. So
what implementation do I give in Animal class for the function sound(), the only and
correct way of doing this would be making this function pure abstract so that I need not
give implementation in Animal class but all the classes that inherits Animal class must
give implementation to this function. This way I am ensuring that all the Animals have
sound but they have their unique sound.
1) As we have seen that any class that has a pure virtual function is an abstract class.
2) We cannot create the instance of abstract class (Animal). For example: If I have
written this line: Animal obj; in the program, it would have caused compilation error.
3) We can create pointer and reference of base abstract class points to the instance of
child class. For example, this is valid: Animal *a;
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Run time polymorphism and function (method) overriding
In contrast, to compile time or static polymorphism, the compiler deduces the object at
run time and then decides which function call to bind to the object. In C++, runtime
polymorphism is implemented using method or function overriding.
Function overriding is the mechanism using which a function defined in the base class is
once again defined in the derived class. In this case, we say the function is overridden in
the derived class.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Output:
print derived class
show base class
Virtual Functions
For the overridden function should be bound dynamically to the function body, we
make the base class function virtual using the “virtual” keyword. This virtual function is
a function that is overridden in the derived class and the compiler carries out late or
dynamic binding for this function.
So in the above class definition of Base, we made print () function as “virtual”. As the
base class function is made virtual, when we assign derived class object to base class
pointer and call print() function, the binding happens at runtime.
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Thus, as the base class pointer contains derived class object, the print () function body
in the derived class is bound to function print () and hence the output.
In C++, the overridden function in derived class can also be private. The compiler only
checks the type of the object at compile time and binds the function at run time, hence it
doesn’t make any difference even if the function is public or private.
Note that if a function is declared virtual in the base class, then it will be virtual in all of
the derived classes.
Virtual functions ensure that the correct function is called for an object,
regardless of the type of reference (or pointer) used for function call.
They are mainly used to achieve Runtime polymorphism
Functions are declared with a virtual keyword in base class.
The resolving of function call is done at Run-time.
Virtual functions cannot be static and also cannot be a friend function of another
class.
Virtual functions should be accessed using pointer or reference of base class type
to achieve run time polymorphism.
The prototype of virtual functions should be same in base as well as derived
class.
They are always defined in base class and overridden in derived class. It is not
mandatory for derived class to override (or re-define the virtual function), in
that case base class version of function is used.
A class may have virtual destructor but it cannot have a virtual constructor.
Special note: The virtual function is bound to the function body accurately at runtime
by using the concept of the virtual table (VTABLE) and a hidden pointer called _vptr.
Both these concepts are internal implementation and cannot be used directly by the
program.
Note: The document presents the notes on Module-III of ‘OOP with C++’. The students has
to use the creativity to answer the questions asked in examination. The answers should be
accompanied with suitable examples, syntax and diagrams (as applicable).
Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University