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

Pure Virtual Functions And Abstract Classes in C++

In this tutorial, we will learn about pure virtual functions and abstract classes in C++. Pure virtual functions are functions that do not have an implementation in the base class and must be overridden by derived classes. Abstract classes are classes that contain at least one pure virtual function and cannot be instantiated directly.

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

  • Create an abstract 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 abstract classes and pure virtual functions:

Now, you can use abstract classes and pure 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 pure virtual functions and abstract classes in C++. By using pure virtual functions and abstract classes, you can define interfaces that derived classes must implement, which helps enforce consistency and promotes code reusability in your object-oriented programs.

  1. How to Create Abstract Classes with Pure Virtual Functions in C++:

    • Abstract classes are classes that contain pure virtual functions. They cannot be instantiated directly.

    Example:

    class AbstractShape {
    public:
        virtual void draw() const = 0; // Pure virtual function
    };
    
  2. Implementing Abstract Base Classes and Concrete Derived Classes in C++:

    • Abstract base classes define interfaces, while concrete derived classes provide specific implementations.

    Example:

    class AbstractShape {
    public:
        virtual void draw() const = 0;
    };
    
    class Circle : public AbstractShape {
    public:
        void draw() const override {
            // Circle-specific draw implementation
        }
    };
    
  3. Virtual Destructors and Pure Virtual Functions in C++:

    • When using abstract classes with pure virtual functions, it's essential to have a virtual destructor for proper destruction in polymorphic scenarios.

    Example:

    class AbstractBase {
    public:
        virtual ~AbstractBase() = 0; // Pure virtual destructor
    };
    
    AbstractBase::~AbstractBase() {
        // Implementation for pure virtual destructor
    }
    
  4. Handling Multiple Inheritance with Abstract Classes and Pure Virtual Functions in C++:

    • Multiple inheritance involving abstract classes requires careful consideration of the diamond problem.

    Example:

    class A {
    public:
        virtual void func() const = 0;
    };
    
    class B : public A {
        // Implementation for func
    };
    
    class C : public A {
        // Implementation for func
    };
    
    class D : public B, public C {
        // Ambiguity due to multiple inheritance
    };
    
  5. Abstract Factory Pattern with Pure Virtual Functions in C++:

    • The abstract factory pattern involves creating families of related or dependent objects without specifying their concrete classes.

    Example:

    class AbstractProductA {
    public:
        virtual void operationA() const = 0;
    };
    
    class ConcreteProductA1 : public AbstractProductA {
        // Implementation for operationA
    };
    
  6. Examples Illustrating Pure Virtual Functions and Abstract Classes in C++:

    • Consider a scenario where different shapes need to be drawn uniformly using an abstract base class.

    Example:

    class AbstractShape {
    public:
        virtual void draw() const = 0;
    };
    
    class Circle : public AbstractShape {
    public:
        void draw() const override {
            // Circle-specific draw implementation
        }
    };
    
    class Square : public AbstractShape {
    public:
        void draw() const override {
            // Square-specific draw implementation
        }
    };