C++ Function Overriding

Function overriding in C++ occurs when a derived class redefines a method that was already defined in its base class. For overriding to work, the following conditions must be met:

  1. The function in the base class should be marked as virtual.
  2. The derived class function must have the same name, return type, and parameters as the function in the base class.

Overriding allows the derived class to change or extend the behavior of the inherited function, which is crucial for implementing polymorphism.

Example 1: Function Overriding with Base Class Pointer

Code Example:

#include <iostream>
using namespace std;

// Base class
class Animal {
public:
virtual void speak() {
cout << “Animal makes a sound.” << endl;
}
};

// Derived class Dog
class Dog : public Animal {
public:
void speak() override {
cout << “Dog barks.” << endl;
}
};

// Derived class Cat
class Cat : public Animal {
public:
void speak() override {
cout << “Cat meows.” << endl;
}
};

int main() {
// Base class pointers
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();

// Calling the overridden functions
animal1->speak(); // Output: Dog barks.
animal2->speak(); // Output: Cat meows.

delete animal1;
delete animal2;

return 0;
}

Explanation:

In this example, the Animal class has a speak() function that is virtual, enabling runtime polymorphism. The derived classes Dog and Cat override the speak() function with their own implementations.

  • The animal1 pointer points to a Dog object, and animal2 points to a Cat object.
  • Even though both animal1 and animal2 are of type Animal*, the appropriate method (either Dog::speak() or Cat::speak()) is called, thanks to dynamic dispatch, which is triggered by the virtual keyword in the base class.

Output:

Dog barks.
Cat meows.

Example 2: Function Overriding with Base Class Reference

Code Example:

#include <iostream>
using namespace std;

// Base class
class Animal {
public:
virtual void speak() {
cout << “Animal makes a sound.” << endl;
}
};

// Derived class Dog
class Dog : public Animal {
public:
void speak() override {
cout << “Dog barks.” << endl;
}
};

// Derived class Cat
class Cat : public Animal {
public:
void speak() override {
cout << “Cat meows.” << endl;
}
};

int main() {
Dog dog;
Cat cat;

// Base class references
Animal& animal1 = dog;
Animal& animal2 = cat;

// Calling the overridden functions
animal1.speak(); // Output: Dog barks.
animal2.speak(); // Output: Cat meows.

return 0;
}

Explanation:

In this example, the Animal class function speak() is virtual, and it is overridden in both the Dog and Cat classes. Instead of using pointers, we use references to refer to the objects. Even though the references are of type Animal&, the correct version of the speak() function is invoked based on the actual object type.

  • animal1 refers to a Dog object, and animal2 refers to a Cat object.
  • Thanks to the virtual keyword, dynamic polymorphism ensures that the appropriate speak() function (either Dog::speak() or Cat::speak()) is called at runtime.

Output:

Dog barks.
Cat meows.