C++ Tutorial

Class and Object

Reference

Inheritance and Derivation

Polymorphism and Virtual Functions

Operator Overloading

Template

Exception

Object Oriented Advanced

Input/Output Stream

File Operations

Polymorphism And Virtual Functions in C++

In this tutorial, we will learn about polymorphism and virtual functions in C++. Polymorphism is a key feature of object-oriented programming that allows you to treat objects of different classes as objects of a common superclass. Virtual functions enable you to achieve runtime polymorphism, which is the ability to call the correct function based on the actual type of an object at runtime.

Let's explore polymorphism and virtual functions using a simple example with Shape, Circle, and Rectangle classes.

  • Create a base Shape class:

First, let's create a base Shape class with a pure virtual function area():

class Shape {
public:
    // Pure virtual function for calculating area
    virtual double area() const = 0;

    // Virtual destructor
    virtual ~Shape() {}
};

The area() function is declared as a pure virtual function with = 0, which makes Shape an abstract class. This means you cannot create objects of type Shape, but you can create pointers and references to Shape. The virtual destructor is important for proper clean-up of derived class objects when they are deleted through a base class pointer.

  • Create derived classes Circle and Rectangle:

Next, let's create two derived classes, Circle and Rectangle, that inherit from Shape and override the area() function:

class Circle : public Shape {
    double radius;

public:
    Circle(double radius) : radius(radius) {}

    double area() const override {
        return 3.14159 * radius * radius;
    }
};

class Rectangle : public Shape {
    double width, height;

public:
    Rectangle(double width, double height) : width(width), height(height) {}

    double area() const override {
        return width * height;
    }
};

Both Circle and Rectangle override the area() function to provide their own implementations for calculating the area.

  • Use polymorphism and virtual functions:

Now, you can use polymorphism and virtual functions to work with objects of different classes through a common base class pointer:

#include <iostream>
#include <vector>

int main() {
    std::vector<Shape*> shapes;

    shapes.push_back(new Circle(5));
    shapes.push_back(new Rectangle(10, 6));

    for (Shape* shape : shapes) {
        std::cout << "Area: " << shape->area() << std::endl;
    }

    for (Shape* shape : shapes) {
        delete shape;
    }

    return 0;
}

In this example, we create a Circle and a Rectangle object and store their addresses in a std::vector of Shape pointers. Then, we iterate through the vector and call the area() function for each shape, which invokes the correct implementation of the area() function based on the actual type of the object. Finally, we delete the objects using base class pointers, which properly calls the destructors for derived class objects due to the virtual destructor in the Shape class.

That's it for our tutorial on polymorphism and virtual functions in C++. By using polymorphism and virtual functions, you can work with objects of different classes in a more uniform manner, enabling you to write more flexible and reusable code.

  1. How to Use Virtual Functions for Polymorphism in C++:

    • Polymorphism allows objects of different classes to be treated as objects of a common base class through virtual functions.

    Example:

    class Shape {
    public:
        virtual void draw() const {
            // Base class draw function
        }
    };
    
    class Circle : public Shape {
    public:
        void draw() const override {
            // Circle-specific draw function
        }
    };
    
    class Square : public Shape {
    public:
        void draw() const override {
            // Square-specific draw function
        }
    };
    
    void displayDrawing(const Shape& shape) {
        shape.draw(); // Polymorphic call
    }
    
  2. Abstract Classes and Pure Virtual Functions in C++:

    • Abstract classes have pure virtual functions, making them incomplete and meant for deriving concrete classes.

    Example:

    class AbstractShape {
    public:
        virtual void draw() const = 0; // Pure virtual function
    };
    
  3. Dynamic Polymorphism with Virtual Functions in C++:

    • Dynamic polymorphism occurs at runtime, allowing the correct function to be called based on the actual type of the object.

    Example:

    Shape* shapePtr = new Circle();
    shapePtr->draw(); // Calls the Circle's draw function dynamically
    
  4. Virtual Function Overriding and Hiding in C++:

    • Overriding occurs when a derived class provides a specific implementation for a virtual function, and hiding happens when a function with the same name is introduced in the derived class.

    Example:

    class Base {
    public:
        virtual void display() const {
            // Base class display function
        }
    };
    
    class Derived : public Base {
    public:
        void display() const override {
            // Derived class-specific display function
        }
    };
    
  5. Polymorphism and Function Pointers in C++:

    • Polymorphism can be achieved using function pointers, providing a level of dynamic dispatch.

    Example:

    void performDrawing(const Shape& shape) {
        void (Shape::*drawFunction)() const = &Shape::draw;
        (shape.*drawFunction)(); // Dynamic dispatch using function pointer
    }
    
  6. Pure Virtual Destructors and Polymorphism in C++:

    • When using polymorphism with base and derived classes, it's essential to have a virtual destructor to ensure proper destruction of objects.

    Example:

    class Base {
    public:
        virtual ~Base() = 0; // Pure virtual destructor
    };
    
    Base::~Base() {
        // Implementation for pure virtual destructor
    }
    
  7. C++ Polymorphism with Interfaces and Abstract Base Classes:

    • Interfaces in C++ are achieved through abstract base classes with pure virtual functions.

    Example:

    class Printable {
    public:
        virtual void print() const = 0;
    };
    
    class Document : public Printable {
    public:
        void print() const override {
            // Document-specific print function
        }
    };