You are on page 1of 63

POLYMORPHISM

 The word polymorphism means having many


forms.
 the ability of a message to be displayed in
more than one form
 E.g,
 a person at the same time can have different
characteristics. Like a man at the same time
is a father, a husband, an employee.
 So the same person posses different
behaviour in different situations.
 This is called polymorphism.
Polymorphism

Compile Time
Polymorphism Run time Polymorphism

Function Operator Function


Overloading Overloading Virtual Function
Overriding
 This is also known as static (or early) binding.
 Function overloading and Operator overloading
are perfect example of Compile time
polymorphism.
 Function Overloading:-
When there are multiple functions with same name
but different parameters then these functions are
said to be overloaded. Functions can be
overloaded by change in number of
arguments or/and change in type of arguments.
Example
Operator Overloading:

 C++ also provide option to overload


operators.

 For example, we can make the operator (‘+’)


for string class to concatenate two strings.
We know that this is the addition operator
whose task is to add two operands.
 So a single operator ‘+’ when placed between
integer operands , adds them and when
placed between string operands,
concatenates them.
 It is also called as dynamic binding.
 Function overriding is an example of Runtime
polymorphism.

Function Overriding: When child class


declares a method, which is already present
in the parent class then this is called function
overriding, here child class overrides the
parent class.
Example
 Operator overloading is a compile-time
polymorphism in which the operator is overloaded to
provide the special meaning to the user-defined data
type.
 Operator overloading is used to overload or redefines
most of the operators available in C++.
 It is used to perform the operation on the user-
defined data type.
 For example, C++ provides the ability to add the
variables of the user-defined data type that is applied
to the built-in data types.
 The advantage of Operators overloading is to perform
different operations on the same operand
int i, j, k; // integers
float m, n, p; // floats The compiler overloads
the + operator for built-in
integer and float types by
k = i + j; default, producing integer
// integer addition and assignment addition with i+j, and
p = m + n; floating addition with m+n.
// floating addition and assignment

We can make object operation look like individual


int variable operation, using operator functions
Complex a,b,c;
c = a + b;
8
 Existing operators can only be overloaded, but the
new operators cannot be overloaded.
 The overloaded operator contains atleast one
operand of the user-defined data type.
 We cannot use friend function to overload certain
operators. However, the member function can be
used to overload those operators.
 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.
 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.
Operators that can be overloaded
+ - * / % ^ & |
~ ! = < > += -= *=
/= %= ^= &= |= << >> >>=
<<= == != <= >= && || ++
-- ->* , -> [] () new delete
new[] delete[]
 the operators that can not be overloaded by
friend function are as follows.

Assignment operator =
function call operator ()
subscriping operator []
class member access operator ->
 The process of overloading involves the
following steps :
1) Create a class that defines the data type
that is to be used in the overloading
operation.
2) Declare the operator function operator op()
in the public part of the class. It may be
either a member function or a friend
function.
3) Define the operator function to implement
the required operations.
 Operator functions must be either member
functions (non-static) or friend functions.

 Basic difference between them is that a friend


function will have only one argument for unary
operators and two for binary operators, while a
member function has no arguments for unary
operators and only one for binary operators.

 because the object used to invoke the member


function is passed implicitly and therefore is
available for the member function. This is not the
case with friend functions.
 Declaration Syntax of operator function :

Examples:
operator+
Return_type operator op(argument-list);
operator-
operator*
--- operator is a function operator/
--- op is one of C++ operator symbols (+, -, =, etc..)

14
 Definition Syntax of operator function :

return_type class_name :: operator op(argument-list)


{

Function body //task defined

15
 Unary operator: are operators that act upon a
single operand to produce a new value.

Types of unary operators:


 unary minus(-)
 increment(++) ++a a++
 decrement(- -)
 NOT(!)
 Addressof operator(&)
 sizeof()
 Example of unary operator overloading
 A binary operator is an operator that operates
on two operands and manipulates them to
return a result.
 You use binary operators very frequently like
addition (+) operator, subtraction (-) operator
and division (/) operator.
 Example of overloading binary operator.
 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 compiler , provided that
the same data type is used on both sides of
the equal sign.
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
2. Conversion between user defined data types
a) Conversion in destination object
b) Conversion in source object
 Conversion from basic to user defined type is
done by using the constructor function with one
argument of basic type as follows.
 Syntax:
class class_name
{ private: //….
public:
class_name ( data_type)
{ // conversion code
}
};
Example
 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:
class class_name
{ ...
public:
operator data_type()
{ //Conversion code
}
};

Example:
 This conversion is exactly like conversion of
basic to user defined data type i.e. one
argument constructor is used.
 Conversion routine is defined as a one
argument constructor in destination class and
takes the argument of the source class type
E.g.
classA objA;
classB objB;
objA=objB;
Here, objB is the source of the
class classB and objA is the destination object
of class classA.
the conversion routine should exist
in classA (destination class type) as a one
argument constructor.
Example
This conversion is exactly like conversion of user-
defined type to basic type i.e. overloading the
cast operator is used.
E.g.
classA objA;
classB objB;
objA=objB;
 objB is the source of the class classB and objA is
the destination object of class classA. Conversion
routine is specified as conversion (cast) operator
overloading for the type of destination class.

//destination object class
class classA
{
//body of classA
} //source object class
class classB { private: //…. public:
operator classA () //cast operator destination
types { //code for conversion from
classB //to classA } };
 Converting an expression of a given type into
another type is known as type-casting.
 There are two types of casting as
1. Implicit Casting
2. Explicit Casting
 Implicit conversions do not require any
operator. They are automatically performed
when a value is copied to a compatible type.
For example:
float a=20.10;
int b;
b=a;
the value is converted from float to int and we
have not had to specify any type-casting
operator.
 This is known as a standard conversion.
 Standard conversions affect fundamental data
types, and allow conversions such as the
conversions between numerical types
(short to int, int to float, double to int...), to or
from bool, and some pointer conversions.
 Some of these conversions may imply a loss of
precision, which the compiler can signal with a
warning.
 This warning can be avoided with an explicit
conversion.
 Implicit conversions also include constructor or operator
conversions, which affect classes that include specific
constructors or operator functions to perform conversions.
 For example:

class A {};
class B {
public: B (A a) {}
};
A a;
B b=a;

Here, an implicit conversion happened between objects


of class A and class B, because B has a constructor that
takes an object of class A as parameter.
Therefore implicit conversions from A to B are allowed.
 For explicit conversion cast operator is used.
 A cast is a special operator that forces one data type
to be converted into another.
 As an operator, a cast is unary and has the same
precedence as any other unary operator.
 The most general cast supported by most of the C++
compilers is as follows −
Where type is the desired data type.

(type) expression
e.g.
float a=20.20;
int b;
b =(int) a;
example
const_cast<type> (expr) −
 The const_cast operator is used to explicitly
override const in a cast.
 The target type must be the same as the
source type except for the alteration of its
const attributes.
 This type of casting manipulates the const
attribute of the passed object, either to be set
or removed.
 Example
dynamic_cast<type> (expr) −
dynamic_cast can be used only with pointers
and references to objects.
Its purpose is to ensure that the result of the
type conversion is a valid complete object of
the requested class.

Therefore, dynamic_cast is always successful


when we cast a class to one of its base
classes:
class CBase { };
class CDerived: public CBase { };

CBase b; CBase* pb;


CDerived d; CDerived* pd;
pb = dynamic_cast<CBase*>(&d); // ok: derived-to-
base
pd = dynamic_cast<CDerived*>(&b); // wrong: base-
to-derived

The second conversion in this piece of code would


produce a compilation error since base-to-derived
conversions are not allowed with dynamic_cast unless
the base class is polymorphic.
static_cast can perform conversions between
pointers to related classes, not only from the
derived class to its base, but also from a base
class to its derived.
This ensures that at least the classes are
compatible if the proper object is converted, but
no safety check is performed during runtime to
check if the object being converted is in fact a
full object of the destination type.
Therefore, it is up to the programmer to ensure
that the conversion is safe.
On the other side, the overhead of the type-safety
checks of dynamic_cast is avoided.
class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a);
 reinterpret_cast<type> (expr) − The
reinterpret_cast operator changes a pointer to
any other type of pointer. It also allows
casting from pointer to an integer type and
vice versa.
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a);
 Precedence and Associativity of an operator
cannot be changed.
 Arity (numbers of Operands) cannot be changed.
Unary operator remains unary, binary remains
binary etc.
 No new operators can be created, only existing
operators can be overloaded.
 Cannot redefine the meaning of a procedure. You
cannot change how integers are added.
 Pre-increment /decrement and post
increment/decrement operator give same output
in operator overloading.
 When an object is declared or created using
the const keyword, its data members can
never be changed, during the object's
lifetime.
 Syntax:
const class_name object
e.g.
const test t(30);
Example
 Mutable data members are those members
whose values can be changed in runtime even
if the object is of constant type. It is just
opposite to constant.
 Sometimes logic required to use only one or
two data member as a variable and another
one as a constant to handle the data. In that
situation, mutability is very helpful concept to
manage classes.
 sometimes there is requirement to modify
one or more data members of class through
const function even though you don’t want
the function to update other members of
class.
 This task can be easily performed by using
mutable keyword.
 Example
 The explicit keyword in C++ is used to mark
constructors to not implicitly convert types. For
example, if you have a class Foo −
class Foo
{
public:
Foo(int n); // allocates n bytes to the Foo
object
Foo(const char *p); // initialize object with char
*p
};
Now in main function if you try
Foo mystring = 'x';
 The char 'x' is implicitly converted to int and
then will call the Foo(int) constructor.
 But this is not what was intended.
 So to prevent such conditions and make the
code less error-prone, define the constructor
as explicit.
class Foo
{
public:
explicit Foo (int n); //allocate n bytes
Foo(const char *p); // initialize with string p
};
 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.
 Example
 A base class pointer can point to a derived
class object, but we can only access base
class member or virtual functions using the
base class pointer
 because object slicing happens when a
derived class object is assigned to a base
class object.
 Additional attributes of a derived class object
are sliced off to form the base class object.
 pointer to a derived class is type-compatible with
a pointer to its base class.
example
 Function main declares two pointers
to Polygon (named ppoly1 and ppoly2). These are
assigned the addresses of rect and trgl,
respectively, which are objects of
type Rectangle and Triangle. Such assignments
are valid, since both Rectangle and Triangle are
classes derived from Polygon.
 Dereferencing ppoly1 and ppoly2 (with *ppoly
1 and *ppoly2) is valid and allows us to
access the members of their pointed objects.
For example, the following two statements
would be equivalent in the previous example:
 ppoly1->set_values (4,5);
 rect.set_values (4,5);
But because the type of ppoly1 and ppoly2 is
pointer to Polygon (and not pointer
to Rectangle nor pointer to Triangle), only the
members inherited from Polygon can be
accessed, and not those of the derived
classes Rectangle and Triangle
 the program above accesses the area members of
both objects using rect and trgl directly, instead
of the pointers; the pointers to the base class
cannot access the area members

.
Member area could have been accessed with the
pointers to Polygon if area were a member
of Polygon instead of a member of its derived
classes, but the problem is
that Rectangle and Triangle implement different
versions of area, therefore there is not a single
common version that could be implemented in
the base class.
 A virtual function is a member function which
is declared within a base class and is re-
defined(Overriden) 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 function.
 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.
 Example
 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.
 NOTE:
If we have created a virtual function in the base
class and it is being overridden in the derived
class then we don’t need virtual keyword in
the derived class, functions are automatically
considered as virtual functions in the derived
class.
 If a class contains a virtual function then
compiler itself does two things:
 If object of that class is created then a virtual
pointer(VPTR) is inserted as a data member of the
class to point to VTABLE of that class.
 For each new object created, a new virtual
pointer is inserted as a data member of that
class.
 Irrespective of object is created or not, a static
array of function pointer called VTABLE where
each cell contains the address of each virtual
function contained in that class
 A pure virtual function (or abstract function)
in C++ is a virtual function for which we
don’t have implementation, we only declare
it.
 A pure virtual function is declared by
assigning 0 in declaration.
Syntax:-
 virtual void show() = 0;
Example:-
 These are the concepts of Run-time
polymorphism.
 Prototype i.e. Declaration of both the
functions remains the same throughout the
program.
 These functions can’t be global or static.
Virtual Function Pure Virtual Function
A virtual function is a member function A pure virtual function is a member
of base class which can be redefined function of base class whose only
by derived class. declaration is provided in base class
and should be defined in derived class
otherwise derived class also becomes
abstract.

Classes having virtual functions are not Base class containing pure virtual
abstract. function becomes abstract.

Syntax:-
Syntax:-
virtual<func_type><func_name>()
virtual<func_type><func_name>()
= 0;
{
// code
}
Definition is given in base class. No definition is given in base class.

Base class having virtual function can Base class having pure virtual function
be instantiated i.e. its object can be becomes abstract i.e. it cannot be
1) A class is abstract if it has at least one pure
virtual function.
2)We can have pointers and references of
abstract class type.
3) If we do not override the pure virtual
function in derived class, then derived class
also becomes abstract class.
4) An abstract class can have constructors.
 Deleting a derived class object using a
pointer of base class type that has a non-
virtual destructor results in undefined
behaviour.
 To correct this situation, the base class
should be defined with a virtual destructor.
 Example:-
 Abstract Class is a class which contains
atleast one Pure Virtual function in it.
 Abstract classes are used to provide an
Interface for its sub classes.
 Classes inheriting an Abstract Class must
provide definition to the pure virtual function,
otherwise they will also become abstract
class.
Thank You

You might also like