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

Polymorphism and virtual functions

The document provides an overview of inheritance and polymorphism in C++, detailing the types of inheritance, the concept of polymorphism, and the mechanisms of function and operator overloading. It explains method overriding, ambiguity in inheritance, virtual functions, and the importance of early and late binding. Additionally, it discusses abstract classes, pure virtual functions, virtual destructors, and the role of friend functions and classes in C++.

Uploaded by

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

Polymorphism and virtual functions

The document provides an overview of inheritance and polymorphism in C++, detailing the types of inheritance, the concept of polymorphism, and the mechanisms of function and operator overloading. It explains method overriding, ambiguity in inheritance, virtual functions, and the importance of early and late binding. Additionally, it discusses abstract classes, pure virtual functions, virtual destructors, and the role of friend functions and classes in C++.

Uploaded by

Aryaman Singh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Inheritance & Polymorphism

Inheritance
• Definition: In C++, inheritance is a process in which one object acquires all
the properties and behaviors of its parent object automatically.

• Code reusability: We can reuse, extend or modify the attributes and behaviors
which are defined in other class

• Types Of Inheritance: C++ supports five types of inheritance:

• Single inheritance
• Multilevel inheritance
• Multiple inheritance
• Hierarchical inheritance
• Hybrid inheritance
MULTIPLE
SINGLE MULTI-LEVEL

Base Class Base Class Base Class-1 Base Class-2

Derived Class Derived Class


Derived Class

Derived Class
HIERARCHICAL

Base Class

Derived Class-1 Derived Class-2


Polymorphism

• Means having many forms. Occurs when we have many classes that are related to
each other by inheritance.

• Two types
1) Compile-time polymorphism (static) - Method overloading and operator
overloading
2) Run-time polymorphism (dynamic) - Method overriding
Overloading
Function overloading :
• Two or more function with the same name, but different in parameters is known as
function overloading in C++.
• The function is redefined by using either different types of arguments or a different
number of arguments. It is only through these differences' compiler can differentiate
between the functions.

void display(int p, int c)


{ ... .. ... }

void display(int p, float c)


{ ... .. ... } // overloaded function
Overloading
Function overloading :

Functions cannot be overloaded by return type alone.

void display()
{ ... .. ... }

int display()
{ ... .. ... } // overloaded function distinguished
only by return type
Overloading
Operator overloading:
Operator overloading is a feature in C++ that allows operators such as +, -, *, /, =, and many
others to be redefined for user-defined types like classes.

returnType operator symbol (arguments)


{ ... .. ... }

Operators that cannot be overloaded :

-> Scope operator (::)


-> Sizeof
-> member selector(.)
-> member pointer selector(*)
-> ternary operator(?:)
Ambiguity in single inheritance in C++ (Method overriding)
• The ambiguity happen when there are functions with the same name and
return type in the base class and the derived class.

• If an object of the derived class accesses such a function, the derived class’s
function is called, which leads to function overriding.

• Scope resolution operator can be used to handle this ambiguous situation.

• Derivedclass_object.baseclass_Name::function() // call base class function


• Derivedclass_object.function() // call derived class function

• * The data members and functions in B with same name as in A hide (or
shadow) those in A. Scope resolution operator can be used to access them.
Method overriding
• Class Box • Int main()
{
….
{
void draw(){print(‘Base’)} TextBox tb;
}; tb.draw();
Class TextBox : public Box
tb.Box::draw();
{
….
void draw(){print(‘Derived’)}
};
The function in the derived class overrides the function in base class.

Use scope resolution operator to invoke base class function


Ambiguity in multiple inheritance in C++
• The base classes may have functions with same name and the derived class
may not have the functions with that names as those of its base classes.

• The compiler gets confused if the derived class object tries to access one of
the similarly named member functions of the base classes.

• Scope resolution operator can be used to handle this ambiguous situation.

• Derivedclass_object.baseclass_Name::function() // call base class function


• Derivedclass_object.function() // call derived class function

• * The data members and functions in B with same name as in A hide (or
shadow) those in A. Scope resolution operator can be used to access them.
Method overriding
• Class Box Class TextBox : public Box, public shape
{ {
…. };
void draw(){print(‘Box’)}
}; Int main(){

Class shape TextBox x;


{ x.Box::draw();
….
void draw(){print(‘Shape’)} }
};
If derived class has function print() which is also present in base classes. The derived class function
overrides it and executes the body of print() inside the derived class.

If not, use scope resolution operator to invoke corresponding base class function
Virtual Functions
class Base
{ void main()
public: {
void print() Derived derived1;
{ // code } Base* base1 = &derived1;
}; base1->print();
}
class Derived : public Base
{
public:
void print()
{ // code }
};

• A virtual function is a member function in the base class that we expect to redefine in
derived classes.
• The above program does not override the print() function in Base class. To make it
override use virtual function in the base class by placing virtual key word before the
function.
Override identifier in c++
class Base
{
public: void main()
virtual void print() {
{ // code } Derived derived1;
}; Base* base1 = &derived1;
base1->print();
class Derived : public Base }
{
public:
void print(int a) override
{ // code }
};
• By using override identifier, we are informing the compiler that we want to override the definition
of a base class virtual function in the derived class.
• In the above program, the user wanted to override the base class virtual function but by mistake
used a different signature of the print() function by including parameters.
• If the override keyword is not present, then the program compiles successfully, and prints body
of base class print() function as overriding will not occur.
Virtual Inheritance Here, the compiler does not understand if it
should access A through C or through B and
class A hence throws error.
{ class D : public B, public C
int x =5; {
}; Int I = 7; The addition of virtual keyword helps in inheriting
}; class A virtually, which guarantees that there is
class B : public A only one instance of base class A among the
{ derived classes.
Int I = 10;
}; void main()
{ Do the following changes to achieve virtual
class C : public A D obj; inheritance
{ cout<<obj.x<<endl;
Int I = 7; }
class B : virtual public A
};
class C : virtual public A

Scope resolution operator can also be used to solve the issue as follows:
cout<<obj.B::x<<endl;
cout<<obj.C::x<<endl;
Abstract Classes and Pure Virtual Functions
• When a class has a pure virtual function as member function, it becomes an
abstract base class.

• Pure virtual function will make sure that certain members are always present in
all the derived classes.

virtual Returntype function_name() = 0;

• Abstract base classes can never be instantiated i.e. an object cannot be created
for this class.
Early and Late Binding

• Binding refers to the process of associating function calls to function definitions.

• It can be either early binding (static or compile-time) or late binding (dynamic or


run-time).
Early Binding
• In early binding, all the information necessary to perform the association is available at
the compile time. By default early binding happens in c++.

• It is faster but is not flexible.

• Takes place using function overloading and operator overloading.

Late Binding
• In late binding, the compiler adds code that identifies the type of object at runtime then
matches the call with the right function definition.

• It is slow, but flexible as it allows us to decide which function to be invoked at run-time.

• This can be achieved using virtual keyword (virtual functions) or function overriding.
Early vs Late binding
class Base
{ void main()
public: {
virtual void print() Derived derived1;
{ // code } Base* base1 = &derived1;
}; base1->print();
}
class Derived : public Base
{
public:
void print()
{ // code }
};

Removing the virtual keyword


leads to Early binding
Virtual destructor

class Base
{ void main()
public: virtual ~Base() {
{“destructor invoked”} Base* base1 = new derived;
}; delete b1;
}
class Derived : public Base
{
public: ~Derived()
{ “Destructor invoked”}
};

Without virtual function only the


base class will be destroyed
Friend functions and Friend classes
• Friend function: A function that can access and manipulate the private and
protected members of a class in which they are declared as friend function.

• It can be global function or a function inside another class.

• Friend class: A class that can access the private and protected members of a
class in which it is declared as friend.

• Friendship between classes is neither mutual nor it can be inherited.

• Use cases: Operator overloading and testing

You might also like