An abstract class in C++ is a class that cannot be instantiated (i objects cannot be created from it). It serves as a blueprint for other classes. An abstract class typically contains one or more pure virtual functions (also known as abstract methods) that must be implemented by its derived classes. Abstract classes provide a way to enforce that certain methods are implemented by any class that derives from it, which is a key part of object-oriented design.
Pure Virtual Functions: An abstract class has at least one pure virtual function. A pure virtual function is declared by assigning = 0 to the function declaration. This makes the function "pure" and forces any derived class to provide its own implementation of this function.
Cannot Be Instantiated: You cannot create objects of an abstract class directly. However, you can create pointers or references to an abstract class type and point them to objects of derived classes.
Can Have Normal Member Functions: While abstract classes must have at least one pure virtual function, they can also have fully implemented functions, data members, and constructors.
Inheritance: Derived classes must override all pure virtual functions from the abstract base class, unless they are also abstract themselves.
Here’s how you declare a pure virtual function and an abstract class in C++:
class AbstractClass {
public:
// Pure virtual function
virtual void pureVirtualFunction() = 0;
// Normal member function
void normalFunction() {
cout << "This is a normal function" << endl;
}
};
In this example:
pureVirtualFunction is a pure virtual function because it is followed by = 0.AbstractClass is an abstract class because it contains a pure virtual function.Let’s consider an example where we define an abstract class for geometric shapes and then create derived classes like Circle and Rectangle that implement the required functionality.
#include <iostream>
#include <cmath> // For M_PI
using namespace std;
// Abstract class
class Shape {
public:
// Pure virtual function
virtual void draw() = 0; // Every shape must implement the draw function
// Pure virtual function
virtual double area() = 0; // Every shape must implement the area function
};
// Derived class: Circle
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() override {
cout << "Drawing a circle" << endl;
}
double area() override {
return M_PI * radius * radius; // Area of circle = πr²
}
};
// Derived class: Rectangle
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
void draw() override {
cout << "Drawing a rectangle" << endl;
}
double area() override {
return width * height; // Area of rectangle = width * height
}
};
int main() {
// Creating objects of derived classes
Shape* shape1 = new Circle(5); // Pointer of type Shape pointing to a Circle
Shape* shape2 = new Rectangle(4, 6); // Pointer of type Shape pointing to a Rectangle
shape1->draw(); // Calls Circle's draw method
cout << "Area of Circle: " << shape1->area() << endl;
shape2->draw(); // Calls Rectangle's draw method
cout << "Area of Rectangle: " << shape2->area() << endl;
// Cleanup
delete shape1;
delete shape2;
return 0;
}
Abstract Base Class (Shape):
Shape class contains two pure virtual functions: draw() and area(). These functions must be overridden in any class that inherits from Shape.Derived Classes (Circle and Rectangle):
Circle and Rectangle are derived from Shape. They implement the draw() and area() methods, providing specific behavior for each type of shape.Pointer to Abstract Class:
Shape* and assign it to objects of derived classes (Circle and Rectangle). This demonstrates polymorphism, as the pointer can refer to any derived object that implements the pure virtual functions.Output:
Drawing a circle
Area of Circle: 78.5398
Drawing a rectangle
Area of Rectangle: 24
Enforce Interface in Derived Classes: Abstract classes allow us to define a common interface that all derived classes must follow. By declaring pure virtual functions in the base class, we ensure that each derived class provides its own implementation of these functions. This is useful in situations where different objects should behave similarly (i.e., they should implement the same functions) but with different implementations.
Polymorphism: Abstract classes provide a way to use polymorphism in C++. By using pointers or references to abstract classes, we can call methods in derived classes without knowing the exact type of the object at compile time. The appropriate function is chosen dynamically at runtime.
Code Reusability: Abstract classes allow common functionality to be placed in the base class, while specialized functionality can be added by derived classes. This enables you to reuse code in the base class and extend it in derived classes, making code easier to maintain and more flexible.
Design Flexibility:
Abstract classes give a way to model real-world objects and their relationships with more flexibility. For example, you can define a general Shape class with specific types of shapes (like Circle and Rectangle) being derived from it, without having to change the client code that uses Shape pointers.
Open this section to load past papers