C++11-Significance of override keyword
Polymorphism is one of the most powerful features of Object Oriented Programming. It allows multiple methods to be implemented from a single interface. When multiple methods are defined with same name and different data types, it creates ambiguities during function calls at run-time. Such ambiguities show up as issues when the product is put to production. Override keyword is used to solve such issues.
A class allows the programmer to define a concept. If ‘Shape’ is defined as a class, the concept of shape is so abstract that it’s hard to define the implementation of ‘Shape’, or the object for ‘Shape’ class. It’s hard to define the area of ‘Shape’. Therefore, we define derived class ‘Circle’, which extends the class ‘Shape’ and class ‘Sphere’ extends the class ‘Circle’. When the member function area is defined, it can represent the area of a Circle or a Sphere. If the radius is defined as r, the area of circle Ac is:
$$ A_c = \pi r^2 $$
Area of sphere As can be defined as:
$$ A_s = 4 \pi r^2 $$
The code can also be accesssed in the github page. The C++ code below illustrates the implementation:
1#include<iostream>
2using namespace std;
3#define pi 3.145926
4class Shape
5{
6 public:
7 Shape();
8 ~Shape();
9 virtual void calculateArea(double )=0;
10};
11
12/*
13 class Circle final:public Shape
14 final keyword is used when I don't want class derived
15 to be inherited further
16 class Circle final: public Shape
17*/
18class Circle:public Shape
19{
20 public:
21 int i,j;
22 Circle();
23 ~Circle();
24 /*
25 Compiler indicates an error if the datatypes
26 do not match. If override keyword is not
27 used, then the compiler does not find the implementation
28 of the calculateArea function in the derived
29 class Sphere and calls the Circle
30 class virtual function.
31 */
32 virtual void calculateArea(double );
33 //virtual void calculateArea(double ) override;
34};
35class Sphere:public Circle
36{
37 public:
38 int x;
39 Sphere();
40 ~Sphere();
41 virtual void calculateArea(int );
42};
43Shape::Shape()
44{
45}
46Shape::~Shape()
47{
48}
49Circle::Circle()
50{
51}
52Circle::~Circle()
53{
54}
55void Circle::calculateArea(double r)
56{
57 double area;
58 area = (pi)*r*r;
59 cout << "Area of the circle with radius " << r << " is " << area << std::endl;
60}
61Sphere::Sphere()
62{
63}
64Sphere::~Sphere()
65{
66}
67void Sphere::calculateArea(int r)
68{
69 double area;
70 area = 4*(pi)*r*r;
71 cout << "Area of the sphere with radius " << r << " is " << area << std::endl;
72}
73int main()
74{
75 Shape *p;
76 Circle c;
77 Sphere s;
78 p=&s;
79 p->calculateArea(5);
80
81 return 0;
82}
The function area can be declared in the base class of Shape, and re-implemented in the derived class of Sphere and Circle. Therefore, virtual function allows multiple implementations to be defined from a single interface. As it’s not possible to define the area for ‘Shape’, the function calcualteArea is declared as the pure virtual function as shown below:
1virtual void calculateArea(double )=0;
The program on github illustrates the base class of Shape and derived classes of Sphere and Circle.
In the main function, pointer to class ‘Shape’ *p points to the derived class Sphere object.
1Shape *p;
2Circle c;
3Sphere s;
4p=&s;
5p->calculateArea(5);
The output of the code is:
1Area of the circle with radius 5 is 78.6481
The function calculateArea is class Circle as:
1 virtual void calculateArea(double );
an in class Sphere, it’s defined as:
1 virtual void calculateArea(int );
The function is re-declared in the derived class with the type int. When the function calculateArea is called with the base class pointer pointing to the derived class object s of type Sphere, the function corresponding to the Circle class is called instead of the function corresponding to the Sphere class. The compiler sees an ambiguity and calls the function implemented in the base class instead of the derived class. This is a common problem in the industry as the classes are implemented by different teams. The code compiles fine, but generates incorrect results during execution. This could cause serious bugs in the code which are quite hard to fix. When the ‘override’ keyword is used in the derived class, the function corresponding to the derived class is called and if there is a mismatch in the data types of the virtual functions in the base class and the derived class, an error is thrown during the compile time.