Fundamentals 9 min read

Mastering Polymorphism in C++: Virtual Functions, Override, and Final

This article explains C++ polymorphism, covering virtual functions, the override and final keywords, pure virtual functions, virtual destructors, vtable implementation, performance considerations, modern C++ improvements, and practical examples with code snippets.

php Courses
php Courses
php Courses
Mastering Polymorphism in C++: Virtual Functions, Override, and Final

Polymorphism: Core Feature of Object-Oriented Programming

Polymorphism (多态) is one of the three major OOP features (encapsulation, inheritance, polymorphism) that allows using a uniform interface to handle different object types. In C++, polymorphism is mainly implemented via virtual functions.

Types of Polymorphism

Compile-time polymorphism: achieved through function overloading and templates.

Run-time polymorphism: achieved through inheritance and virtual functions (focus of this chapter).

Virtual Function Basics

Virtual functions are member functions declared with the virtual keyword, allowing derived classes to override the base class implementation.

Basic Syntax

class Base {
public:
    virtual void show() { // virtual function declaration
        cout << "Base class show()" << endl;
    }
};

class Derived : public Base {
public:
    void show() override { // override virtual function
        cout << "Derived class show()" << endl;
    }
};

Usage Example

int main() {
    Base* b = new Derived(); // base pointer to derived object
    b->show(); // outputs "Derived class show()"
    delete b;
    return 0;
}

override Keyword

C++11 introduced the override keyword to explicitly indicate that a function overrides a base class virtual function.

Why Use override?

Improves code readability.

Compiler checks that the function truly overrides a base virtual function.

Prevents accidental creation of new functions due to spelling errors.

Pure Virtual Functions and Abstract Classes

Pure virtual functions are declared in a base class without implementation, making the class abstract.

Syntax

class AbstractBase {
public:
    virtual void pureVirtual() = 0; // pure virtual function
};

class Concrete : public AbstractBase {
public:
    void pureVirtual() override {
        cout << "Implemented pure virtual function" << endl;
    }
};

Characteristics

Classes containing pure virtual functions cannot be instantiated.

Derived classes must implement all pure virtual functions to be instantiable.

Used to define interface specifications.

Virtual Destructors

If a base class pointer points to a derived object and the base destructor is not virtual, the derived part may not be destroyed correctly.

Correct Example

class Base {
public:
    virtual ~Base() {
        cout << "Base destructor" << endl;
    }
};

class Derived : public Base {
public:
    ~Derived() override {
        cout << "Derived destructor" << endl;
    }
};

int main() {
    Base* b = new Derived();
    delete b; // correctly calls derived and base destructors
    return 0;
}

Output: Derived destructor Base destructor

Implementation of Polymorphism: vtable

C++ implements run-time polymorphism via a virtual function table.

Each class with virtual functions has its own vtable.

Each object contains a pointer (vptr) to its class's vtable.

Calling a virtual function uses the vptr to locate the correct implementation.

Memory Layout Example

Derived object:
+-------------------+
| vptr              | --> Derived class vtable
| Base class members|
| Derived class members|
+-------------------+

Performance Considerations

Space overhead: each class with virtual functions maintains a vtable; each object stores a vptr.

Time overhead: virtual calls add an extra indirection.

Optimization suggestions:

Avoid overusing virtual functions.

Consider alternative designs for performance‑critical paths.

Use the final keyword to limit further overriding when not needed.

Modern C++ Improvements

final Keyword

Prevents derived classes from overriding a virtual function or inheriting from a class.

class Base {
public:
    virtual void notOverrideable() final {}
};

class Derived : public Base {
    // void notOverrideable() override {} // error: cannot override final function
};

class FinalClass final {};
// class TryDerived : public FinalClass {}; // error: cannot inherit from final class

Combining override and final

class Base {
public:
    virtual void canOverride() {}
    virtual void mustOverride() = 0;
};

class Derived : public Base {
public:
    void canOverride() override final {}
    void mustOverride() override final {};
};

Practical Example: Graphics Drawing System

class Shape {
public:
    virtual void draw() const = 0;
    virtual ~Shape() = default;
};

class Circle : public Shape {
public:
    void draw() const override {
        cout << "Drawing a circle" << endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() const override {
        cout << "Drawing a rectangle" << endl;
    }
};

void drawAll(const vector<Shape*>& shapes) {
    for (auto shape : shapes) {
        shape->draw(); // polymorphic call
    }
}

int main() {
    vector<Shape*> shapes = {new Circle(), new Rectangle()};
    drawAll(shapes);
    // cleanup...
    return 0;
}

Common Pitfalls

Object slicing: assigning a derived object to a base object cuts off derived parts.

Calling virtual functions in constructors: does not exhibit polymorphic behavior.

Virtual function default arguments: defaults are statically bound; avoid using them.

Virtual functions in multiple inheritance: vtable becomes more complex; design carefully.

Summary

Virtual functions are the key mechanism for run‑time polymorphism.

The override keyword improves safety and readability.

Pure virtual functions define interface contracts.

Base class destructors should always be virtual.

Understanding vtables helps grasp how polymorphism works under the hood.

Modern C++ adds final and other keywords to give finer control over polymorphism.

Polymorphism is one of the most powerful features of object‑oriented programming; mastering virtual functions enables flexible, extensible system architectures.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CPolymorphismvirtual functionsVTableOverrideAbstract Classfinal
php Courses
Written by

php Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.