Introduction
Before discussing the major differences and features of pure virtual and default virtual functions in C++, we must know what they are, so let us summarize them and understand them clearly with code. A virtual function makes its class a polymorphic base class. Derived classes can override virtual functions. Virtual functions called through base class pointers/references will be resolved at run-time. That is, the dynamic type of the object is used instead of its static type:
Derived d;
Base& rb = d;
// if Base::f() is virtual and Derived overrides it, Derived::f() will be called
rb.f();
A pure virtual function is a virtual function whose declaration ends in =0:
class Base {
// ...
virtual void f() = 0;
// ...
}
A pure virtual function implicitly makes the class it is defined for abstract (unlike in Java where you have a keyword to explicitly declare the class abstract). Abstract classes cannot be instantiated. Derived classes need to override/implement all inherited pure virtual functions. If they do not, they too will become abstract.
An interesting 'feature' of C++ is that a class can define a pure virtual function that has an implementation. (What that's good for is debatable.)
Note that C++11 brought a new use for the delete and default keywords which looks similar to the syntax of pure virtual functions:
my_class(my_class const &) = delete;
my_class& operator=(const my_class&) = default;
What is a Virtual function?
It is a member function that is declared within the parent class and can be redefined by the child class.
C++ code:
#include <iostream>
using namespace std;
class parent
{
public:
void print()
{
cout << "Parent class" << endl;
}
};
class child1 : public parent
{
public:
void print()
{
cout << "child class 1" << endl;
}
};
class child2 : public parent
{
public:
void print()
{
cout << "child class 2" << endl;
}
};
int main()
{
parent *p;
child1 c1;
child2 c2;
p=&c1;
p->print();
p=&c2;
p->print();
return 0;
}
Output:
Parent class
Parent class
In the above code, we have not used the virtual method. We have created a parent class that contains the print() function. The two classes are also created, named ‘child1’ and 'child2', that inherit the properties of the parent class. Both 'child1' and 'child2' classes have redefined the print() function. Inside the main() method, the class parent's pointer variable 'p' is declared. The objects of classes child1 and child2 are c1 and c2, respectively. Although the 'p' contains the addresses of c1 and c2 when calling the print() function, it always calls the print() method of the parent class rather. Also, calling the functions of the child1 and child2 classes.
To conquer the above problem, we must make the print method virtual in the parent class. So, virtual means that the approach exists. However, now no longer in reality. We could make the function or method virtual by adding the keyword ‘virtual.’ In the program, we saw earlier, we have to add the virtual keyword just before the print() function in the parent class. It would be more clear with the code below.
virtual void parent()
{
cout << "Parent class" << endl;
}
Output:
child class 1
child class 2
Why is this happening?
In the earlier program, we saw compile-time polymorphism, and here It is a run-time polymorphism.
Both the parent class and the child classes have the same function with the same name, and the parent class is assigned with an address of the child class object, also pointer will run the parent class function.
Later we have made the parent class function virtual, then the compiler will know that it has to do late binding or we can say the run time polymorphism and have to execute the print function in the child class.