News & UpdatesProgrammingWeb programming StoreMy Projects
Links
Affiliates

C++ Tutorial – 16 – Overriding

A new method in a derived class can redefine a method in a base class in order to give it a new implementation.

Hiding derived members

In the example below, Rectangle’s getArea method is redeclared in Triangle with the same signature. The signature includes the name, parameter list and return type of the method.

class Rectangle
{
 public:
  int x, y;
  int getArea() { return x * y; }
};
 
class Triangle : public Rectangle
{
 public:
  Triangle(int a, int b) { x = a; y = b; }
  int getArea() { return x * y / 2; }
};

If a Triangle object is created and the getArea method is invoked, then Triangle’s version of the method will get called.

Triangle t = Triangle(2,3);
t.getArea(); // 3 (2*3/2) calls Triangle's version

However, if the Triangle is upcast to a Rectangle then Rectangle’s version will get called instead.

Rectangle& r = t;
r.getArea(); // 6 (2*3) calls Rectangle's version

That is because the redefined method has only hidden the inherited method. This means that Triangle’s implementation is redefined downwards in the class hierarchy to any child classes of Triangle, but not upwards to the base class.

Overriding derived members

In order to redefine a method upwards in the class hierarchy – what is called overriding – the method needs to be declared with the virtual modifier in the base class. This modifier allows the method to be overridden in derived classes.

class Rectangle
{
 public:
  int x, y;
  virtual int getArea() { return x * y; }
};

Calling the getArea method from Rectangle’s interface will now invoke Triangle’s implementation.

Rectangle& r = t;
r.getArea(); // 3 (2*3/2) calls Triangle's version

Base class scoping

It is still possible to access a redefined method from a derived class by typing the class name followed by the scope resolution operator. This is called base class scoping and can be used to allow access to redefined methods that are any number of levels deep in the class hierarchy.

class Triangle : public Rectangle
{
 public:
  Triangle(int a, int b) { x = a; y = b; }
  int getArea() { return Rectangle::getArea() / 2; }
};

Calling base class constructor

Another place where base class scoping is important is in the constructors of derived classes. In C++, constructors in derived classes will implicitly call the parameterless base class constructor. To call another base class constructor it will need to be explicitly invoked at the beginning of the derived constructor’s initialization list.

class Rectangle
{
 public:
  int x, y;
  Rectangle(int a, int b) { x = a; y = b; }
};
 
class Triangle : public Rectangle
{
 public:
  Triangle(int a, int b) : Rectangle(a,b) {}
};

Note that the base class constructor does not have to be qualified with the class name.

Recommended additional reading:
Sams - Teach Yourself C++ in One Hour a Day