abstract_class


Concept: abstract class

An abstract class in C++ is a class that cannot be instantiated on its own and is designed to serve as a base class for other classes. An abstract class is defined by having at least one pure virtual function—a function that is declared but not defined within the class. Derived classes must provide an implementation for these pure virtual functions, or they too will be considered abstract classes.

Key Characteristics of Abstract Classes

Example 1: Defining and Using an Abstract Class

Here's a simple example demonstrating the concept of an abstract class in C++:

include <iostream>

// Define an abstract class with a pure virtual function
class Shape {
public:
    virtual void draw() const = 0;  // Pure virtual function
    virtual double area() const = 0; // Another pure virtual function
};

class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}

    void draw() const override {
        std::cout << "Drawing Circle." << std::endl;
    }

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

private:
    double radius;
};

class Rectangle : public Shape {
public:
    Rectangle(double w, double h) : width(w), height(h) {}

    void draw() const override {
        std::cout << "Drawing Rectangle." << std::endl;
    }

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

private:
    double width, height;
};

int main() {
    Circle circle(5.0);
    Rectangle rectangle(4.0, 6.0);

    Shape* shapes[] = { &circle, &rectangle };

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

    return 0;
}

Explanation:

Example 2: Abstract Class as an Interface

In C++, abstract classes are often used to define an interface—a set of pure virtual functions that derived classes must implement. This ensures that all derived classes share a common interface.

include <iostream>

// Abstract class acting as an interface
class Logger {
public:
    virtual void logInfo(const std::string& message) = 0;
    virtual void logWarning(const std::string& message) = 0;
    virtual void logError(const std::string& message) = 0;
};

class ConsoleLogger : public Logger {
public:
    void logInfo(const std::string& message) override {
        std::cout << "INFO: " << message << std::endl;
    }

    void logWarning(const std::string& message) override {
        std::cout << "WARNING: " << message << std::endl;
    }

    void logError(const std::string& message) override {
        std::cout << "ERROR: " << message << std::endl;
    }
};

class FileLogger : public Logger {
public:
    void logInfo(const std::string& message) override {
        // Imagine this writes to a file
        std::cout << "Writing INFO to file: " << message << std::endl;
    }

    void logWarning(const std::string& message) override {
        // Imagine this writes to a file
        std::cout << "Writing WARNING to file: " << message << std::endl;
    }

    void logError(const std::string& message) override {
        // Imagine this writes to a file
        std::cout << "Writing ERROR to file: " << message << std::endl;
    }
};

int main() {
    ConsoleLogger consoleLogger;
    FileLogger fileLogger;

    consoleLogger.logInfo("Application started.");
    fileLogger.logError("File not found.");

    return 0;
}

Explanation:

Example 3: Partial Implementation in Abstract Classes

An abstract class can provide a partial implementation of some functions while leaving others as pure virtual functions.

include <iostream>

class Animal {
public:
    virtual void makeSound() const = 0;  // Pure virtual function

    void breathe() const {  // Regular function
        std::cout << "Animal is breathing." << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() const override {
        std::cout << "Woof!" << std::endl;
    }
};

int main() {
    Dog dog;
    dog.breathe();   // Calls the base class implementation
    dog.makeSound(); // Calls the derived class implementation

    return 0;
}

Explanation:

Summary

Understanding abstract classes is crucial for designing flexible and reusable object-oriented systems in C++. They allow you to define common interfaces and ensure that derived classes adhere to specific requirements, making your code more modular and easier to maintain.

Previous Page | Course Schedule | Course Content