Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Industrial programming >> C Language

Mastering C++ Virtual Functions: Concepts, Examples, and the Override Keyword

C++ Virtual Functions

This tutorial explains C++ virtual functions, their purpose, and practical usage illustrated with code examples.

A virtual function is a base‑class member that we expect derived classes to override. Declaring a function virtual ensures that the most derived implementation is invoked, even when accessed through a base‑class pointer or reference.

When a base class contains a non‑virtual member, calling that member via a base pointer will always execute the base version, regardless of the actual object type. Consider the following:

class Base {
public:
    void print() {
        // base implementation
    }
};

class Derived : public Base {
public:
    void print() {
        // derived implementation
    }
};

In the program below, a Base* points to a Derived instance, yet print() resolves to the base version:

int main() {
    Derived derived1;
    Base* base1 = &derived1;
    base1->print(); // calls Base::print()
    return 0;
}

To achieve polymorphic behavior, declare the function as virtual in the base class:

class Base {
public:
    virtual void print() {
        // base implementation
    }
};

Virtual functions are central to C++ polymorphism. For a deeper dive, see our C++ Polymorphism guide.


Example 1: Basic Virtual Function Usage

#include <iostream>
using namespace std;

class Base {
public:
    virtual void print() {
        cout << "Base Function" << endl;
    }
};

class Derived : public Base {
public:
    void print() override {
        cout << "Derived Function" << endl;
    }
};

int main() {
    Derived derived1;
    Base* base1 = &derived1;
    base1->print(); // prints Derived Function
    return 0;
}

Output

Derived Function

Because Base::print is virtual, the call dispatches to Derived::print even through a base pointer.

Mastering C++ Virtual Functions: Concepts, Examples, and the Override Keyword

The C++ Override Identifier

Since C++11, the override keyword helps prevent accidental mis‑overriding by forcing the compiler to verify that a function truly overrides a virtual base member.

Example:

class Base {
public:
    virtual void print() {
        // base implementation
    }
};

class Derived : public Base {
public:
    void print() override {
        // derived implementation
    }
};

If you define the overriding function outside the class, use:

class Derived : public Base {
public:
    void print() override; // declaration
};

void Derived::print() {
    // implementation
}

Using override Safely

Without override, a typo or signature mismatch silently results in a new function rather than an override, leading to subtle bugs. The compiler will then emit an error, making the issue immediately visible. Common pitfalls include:


Practical Use of Virtual Functions

Consider an Animal base class with derived Dog and Cat classes. Each class holds a type member initialized by its constructor.

class Animal {
private:
    string type;
public:
    Animal() : type("Animal") {}
    virtual string getType() const { return type; }
};

class Dog : public Animal {
private:
    string type;
public:
    Dog() : type("Dog") {}
    string getType() const override { return type; }
};

class Cat : public Animal {
private:
    string type;
public:
    Cat() : type("Cat") {}
    string getType() const override { return type; }
};

With getType() virtual, a single helper can print any animal:

void print(Animal* ani) {
    cout << "Animal: " << ani->getType() << endl;
}

Usage in main():

int main() {
    Animal* animal1 = new Animal();
    Animal* dog1 = new Dog();
    Animal* cat1 = new Cat();

    print(animal1);
    print(dog1);
    print(cat1);

    delete animal1;
    delete dog1;
    delete cat1;
    return 0;
}

Output

Animal: Animal
Animal: Dog
Animal: Cat

By making getType() virtual, we avoid duplicating print() logic in each derived class and ensure that the correct type is accessed.


C Language

  1. Mastering C++ Functions: From Basics to Advanced Usage
  2. C++ Function Overloading: A Practical Guide
  3. Master C++ Inheritance: Build Powerful Classes with Reusable Code
  4. C++ Function Overriding Explained – Practical Examples & Best Practices
  5. C++ Friend Functions and Friend Classes: Mastering Access Control
  6. Mastering C++ Class Templates: A Practical Guide
  7. Mastering C Functions: User-Defined and Standard Library Basics
  8. C++ Functions Explained with Practical Code Examples
  9. Mastering C Functions: Structure, Declaration, and Best Practices
  10. Understanding Polymorphism in C++: A Practical Guide