Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

C++ Polymorphism Virtual Functions Overloading: Tutorial, Examples, FAQs & Interview Tips

What is Polymorphism?

Polymorphism means "many forms" - the same function name behaves differently depending on the object it's called on. C++ supports two types:

  • Compile-time (static) - function overloading, operator overloading. Resolved at compile time.
  • Runtime (dynamic) - virtual functions. Resolved at runtime via vtable.

Runtime Polymorphism - virtual Functions

Mark a base class method as virtual to allow derived classes to override it. Use a base class pointer/reference to call the correct derived version at runtime.

virtual Functions and override
#include <iostream>
using namespace std;

class Shape {
public:
    virtual double area() const {  // virtual - can be overridden
        return 0.0;
    }
    virtual void describe() const {
        cout << "I am a shape with area: " << area() << endl;
    }
    virtual ~Shape() {}  // virtual destructor - ALWAYS add for base classes
};

class Circle : public Shape {
    double radius;
public:
    Circle(double r) : radius(r) {}
    double area() const override {  // override keyword (C++11) - compile-time check
        return 3.14159 * radius * radius;
    }
};

class Rectangle : public Shape {
    double w, h;
public:
    Rectangle(double w, double h) : w(w), h(h) {}
    double area() const override { return w * h; }
};

class Triangle : public Shape {
    double base, height;
public:
    Triangle(double b, double h) : base(b), height(h) {}
    double area() const override { return 0.5 * base * height; }
};

int main() {
    // Base class pointer - runtime polymorphism
    Shape *shapes[] = {
        new Circle(5),
        new Rectangle(4, 6),
        new Triangle(3, 8)
    };

    for (Shape *s : shapes) {
        s->describe();  // calls correct area() for each type
        delete s;
    }

    return 0;
}

/*
Output:
I am a shape with area: 78.5397
I am a shape with area: 24
I am a shape with area: 12
*/

Operator Overloading

C++ lets you redefine how operators (+, -, <<, etc.) work for your custom types.

Operator Overloading
#include <iostream>
using namespace std;

class Vector2D {
public:
    double x, y;
    Vector2D(double x = 0, double y = 0) : x(x), y(y) {}

    // Overload +
    Vector2D operator+(const Vector2D &other) const {
        return Vector2D(x + other.x, y + other.y);
    }

    // Overload ==
    bool operator==(const Vector2D &other) const {
        return x == other.x && y == other.y;
    }

    // Overload << for cout (friend function)
    friend ostream& operator<<(ostream &os, const Vector2D &v) {
        os << "(" << v.x << ", " << v.y << ")";
        return os;
    }
};

int main() {
    Vector2D v1(1, 2), v2(3, 4);
    Vector2D v3 = v1 + v2;

    cout << "v1 = " << v1 << endl;  // (1, 2)
    cout << "v2 = " << v2 << endl;  // (3, 4)
    cout << "v1+v2 = " << v3 << endl;  // (4, 6)
    cout << boolalpha << (v1 == v2) << endl;  // false

    return 0;
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.