Virtual Functions in C++
- Virtual Functions in C++
- Rules of Virtual Functions in C++
- Understanding Pure Virtual Functions in C++
This article will teach about virtual
functions in C++. Virtual functions are special member functions that are either overloaded or overridden by the derived declared but defined and declared in a base class.
Virtual Functions in C++
The keyword virtual
is prepended before the function declaration in the base class. This makes the compiler do late binding, also known as dynamic linkage on the function.
Late-binding or dynamic-linkage at runtime compiler decides the object type and binds the function call. In simple words, it’s a type of binding where the function call is resolved during runtime.
Runtime polymorphism is achieved using these functions. So whenever a function in C++ is made virtual, the compiler at runtime decides which function it has to call based on the object pointed by the base class pointer.
Example code:
#include <bits/stdc++.h>
using namespace std;
class demo {
public:
virtual void fun() { cout << "Inside the base class\n"; }
void check() { cout << "Base class function\n"; }
};
class derived : public demo {
public:
void fun() { cout << "Inside the derived class\n"; }
void check() { cout << "Derived class fuction\n"; }
};
int main() {
demo *ptr;
derived d;
ptr = &d;
ptr->fun();
ptr->check();
}
Output:
Inside the derived class
Base class function
In the above code, since ptr->fun()
is a virtual function, it is binded at runtime, whereas ptr->check()
is a non-virtual function, so it is binded at compile time. Here the runtime polymorphism was achieved using the base class pointer, which points to the object of the derived class.
Rules of Virtual Functions in C++
We must keep the following rules in mind when working with virtual functions.
-
We cannot have virtual constructors, but we can have a virtual destructor. Using virtual destructors ensures that derived class objects are destroyed in the correct order; first, the base class object is destroyed, and then the derived class is destroyed.
Example code:
#include <bits/stdc++.h> using namespace std; class demo { public: demo() { cout << "Constructing base class\n"; } virtual ~demo() { cout << "Destroying base class\n"; } }; class derived : public demo { public: derived() { cout << "Constructing derived class\n"; } virtual ~derived() { cout << "Destroying the derived class\n"; } }; int main() { demo *ptr; derived *derivedPtr = new derived(); ptr = derivedPtr; delete ptr; }
Output: We can observe that the proper construction and destruction order is followed.
Constructing base class Constructing derived class Destroying the derived class Destroying base class
- Only base class pointers or base class references should be used with virtual functions when we want to achieve runtime polymorphism.
- Virtual functions can never be static.
- The virtual function prototype should remain the same in the base and derived classes.
- Virtual functions can also be a
friend
function of another class.
Understanding Pure Virtual Functions in C++
These functions are slight variations of the original virtual functions. A pure virtual function is a do-nothing virtual function.
Syntax:
virtual void fun() = 0
Pure virtual functions are used to create abstract classes. These are classes whose objects cannot be created, and the classes that derive from these should override the pure virtual function; else, they will also be treated as an abstract class.
Example code:
#include <bits/stdc++.h>
using namespace std;
class demo {
public:
virtual void fun() = 0;
};
class derived : public demo {
public:
void fun() // overriding the function
{
cout << "Inside the derived class";
}
};
int main() {
demo *ptr;
// demo d; This will give compile error as base class demo is abstract class
derived d;
ptr = &d;
ptr->fun();
}
Output:
Inside the derived class