C++ Abstract Classes

Creating blueprints with pure virtual functions

🎯 What are Abstract Classes?

Abstract classes contain at least one pure virtual function and cannot be instantiated. They serve as blueprints for derived classes to implement specific functionality.


// Abstract class example
class Animal {
public:
    virtual void sound() = 0;  // Pure virtual function
    virtual void move() = 0;   // Pure virtual function
    
    void sleep() {             // Regular function
        cout << "Animal is sleeping" << endl;
    }
};
                                    

Note:

Cannot create: Animal a; // Error!
Must inherit and implement pure virtual functions

Abstract Class Features

🚫

Cannot Instantiate

Abstract classes cannot create objects

// Error: Cannot instantiate abstract class
// Shape s; // Compilation error
🎯

Pure Virtual Functions

Functions that must be implemented

virtual void draw() = 0;  // Pure virtual
virtual double area() = 0; // Must implement
🏗️

Blueprint Design

Defines interface for derived classes

class Derived : public Abstract {
    void draw() override { /* implementation */ }
};
🔗

Pointer References

Can use pointers and references

Abstract* ptr = new Derived();
Abstract& ref = derivedObject;

🔹 Complete Abstract Class Example

Abstract classes define a common interface for derived classes while allowing partial implementation. For example, a Vehicle abstract class may declare abstract methods like startEngine() and provide concrete methods like honk(). Derived classes such as Car and Motorcycle then implement the specific behaviors, enabling polymorphism and ensuring a consistent structure across related objects.

// Abstract base class
class Vehicle {
protected:
    string brand;
    int year;

public:
    Vehicle(string b, int y) : brand(b), year(y) {}
    
    // Pure virtual functions (must be implemented)
    virtual void start() = 0;
    virtual void stop() = 0;
    virtual double getFuelEfficiency() = 0;
    
    // Regular virtual function (can be overridden)
    virtual void displayInfo() {
        cout << "Brand: " << brand << ", Year: " << year << endl;
    }
    
    // Regular function (inherited as-is)
    void honk() {
        cout << "Beep! Beep!" << endl;
    }
    
    // Virtual destructor (important for abstract classes)
    virtual ~Vehicle() {}
};

// Concrete derived class
class Car : public Vehicle {
private:
    int doors;

public:
    Car(string b, int y, int d) : Vehicle(b, y), doors(d) {}
    
    // Implementing pure virtual functions
    void start() override {
        cout << "Car engine started with key" << endl;
    }
    
    void stop() override {
        cout << "Car engine stopped" << endl;
    }
    
    double getFuelEfficiency() override {
        return 25.5; // miles per gallon
    }
    
    // Overriding virtual function
    void displayInfo() override {
        Vehicle::displayInfo();
        cout << "Doors: " << doors << endl;
    }
};

// Another concrete derived class
class Motorcycle : public Vehicle {
private:
    bool hasSidecar;

public:
    Motorcycle(string b, int y, bool sidecar) 
        : Vehicle(b, y), hasSidecar(sidecar) {}
    
    void start() override {
        cout << "Motorcycle started with kick/button" << endl;
    }
    
    void stop() override {
        cout << "Motorcycle engine stopped" << endl;
    }
    
    double getFuelEfficiency() override {
        return 45.0; // miles per gallon
    }
    
    void displayInfo() override {
        Vehicle::displayInfo();
        cout << "Has sidecar: " << (hasSidecar ? "Yes" : "No") << endl;
    }
};

int main() {
    // Cannot create: Vehicle v; // Error!
    
    // Create concrete objects
    Car car("Toyota", 2022, 4);
    Motorcycle bike("Honda", 2021, false);
    
    // Use polymorphism with abstract class pointers
    Vehicle* vehicles[] = {&car, &bike};
    
    for(int i = 0; i < 2; i++) {
        vehicles[i]->displayInfo();
        vehicles[i]->start();
        cout << "Fuel efficiency: " << vehicles[i]->getFuelEfficiency() 
             << " mpg" << endl;
        vehicles[i]->honk();
        vehicles[i]->stop();
        cout << "---" << endl;
    }
    
    return 0;
}

Output:

Brand: Toyota, Year: 2022
Doors: 4
Car engine started with key
Fuel efficiency: 25.5 mpg
Beep! Beep!
Car engine stopped
---
Brand: Honda, Year: 2021
Has sidecar: No
Motorcycle started with kick/button
Fuel efficiency: 45 mpg
Beep! Beep!
Motorcycle engine stopped

🔹 Interface-like Abstract Classes

Interface-like abstract classes contain only pure virtual functions, serving as strict contracts for derived classes. They define what methods must be implemented without providing any functionality themselves. This is common in languages like C++ to simulate interfaces, ensuring that all subclasses adhere to a specific API, which promotes consistency and enables flexible, decoupled system design.

// Pure interface (all functions are pure virtual)
class Drawable {
public:
    virtual void draw() = 0;
    virtual void setColor(string color) = 0;
    virtual void setPosition(int x, int y) = 0;
    virtual ~Drawable() {} // Virtual destructor
};

class Printable {
public:
    virtual void print() = 0;
    virtual void setPrintSettings(string settings) = 0;
    virtual ~Printable() {}
};

// Multiple inheritance from abstract classes
class Document : public Drawable, public Printable {
private:
    string content;
    string color;
    int x, y;

public:
    Document(string c) : content(c), color("black"), x(0), y(0) {}
    
    // Implementing Drawable interface
    void draw() override {
        cout << "Drawing document at (" << x << ", " << y 
             << ") with color " << color << endl;
    }
    
    void setColor(string c) override {
        color = c;
    }
    
    void setPosition(int px, int py) override {
        x = px; y = py;
    }
    
    // Implementing Printable interface
    void print() override {
        cout << "Printing: " << content << endl;
    }
    
    void setPrintSettings(string settings) override {
        cout << "Print settings: " << settings << endl;
    }
};

int main() {
    Document doc("Hello World!");
    
    // Use as Drawable
    Drawable* drawable = &doc
    drawable->setColor("blue");
    drawable->setPosition(10, 20);
    drawable->draw();
    
    // Use as Printable
    Printable* printable = &doc
    printable->setPrintSettings("High Quality");
    printable->print();
    
    return 0;
}

Output:

Drawing document at (10, 20) with color blue
Print settings: High Quality
Printing: Hello World!

🧠 Test Your Knowledge

What makes a class abstract in C++?