An abstract class in C++ is a class that is designed to serve as a base or blueprint for other classes but cannot be instantiated itself. It contains one or more pure virtual functions, which are virtual functions without any implementation in the abstract class. An abstract class provides an interface for its derived classes to inherit from and implement the pure virtual functions according to their specific needs.
Here's an example of an abstract class in C++:
#include <iostream>
// Abstract class
class Shape {
public:
// Pure virtual function
virtual void draw() = 0;
// Non-virtual function
void print() {
std::cout << "Printing from the Shape class." << std::endl;
}
};
// Derived class 1
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a circle." << std::endl;
}
};
// Derived class 2
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a rectangle." << std::endl;
}
};
int main() {
// Shape shape; // Error: Cannot instantiate an abstract class
Circle circle;
circle.draw(); // Output: Drawing a circle.
circle.print(); // Output: Printing from the Shape class.
Rectangle rectangle;
rectangle.draw(); // Output: Drawing a rectangle.
rectangle.print(); // Output: Printing from the Shape class.
return 0;
}
In this example, the Shape
class is an abstract class with a pure virtual function draw()
. It cannot be instantiated because of the presence of the pure virtual function.
The Circle
and Rectangle
classes are derived from the Shape
class and provide their own implementation of the draw()
function. They must override the pure virtual function from the base class to become concrete classes.
In the main()
function, we create objects of the Circle
and Rectangle
classes. We can call the draw()
function on these objects, which will execute the appropriate implementation based on their respective types.
Abstract classes are useful when we want to define a common interface for a group of related classes but do not want to allow instances of the abstract class itself. It provides a way to enforce a specific set of functions that derived classes must implement while allowing common functionality to be defined in the abstract class.
Advantages of using abstract classes:
- Provides a common interface: Abstract classes allow you to define a common interface or contract that derived classes must adhere to. This ensures consistency and promotes code reusability. By using abstract classes, you can enforce a set of functions that derived classes must implement, which can be beneficial in large projects with multiple developers.
- Supports code organization and modularity: Abstract classes help organize code by separating common behavior and characteristics into a base class. This promotes modularity, as you can define shared functionality in the abstract class and avoid duplicating code in multiple derived classes.
- Enables polymorphism and runtime polymorphic behavior: Abstract classes are essential for achieving runtime polymorphism. Since abstract classes cannot be instantiated directly, pointers or references of the abstract class type can be used to refer to objects of derived classes. This allows for dynamic dispatch of function calls and facilitates polymorphic behavior, where different derived classes can respond differently to the same function call.
Disadvantages of using abstract classes:
- Restricts single inheritance: In C++, a class can only inherit from one base class. When using an abstract class as a base, it limits the ability to inherit from other classes. This restriction may be a limitation in certain scenarios where multiple inheritance is required.
- Adds complexity to the design: Abstract classes introduce an additional layer of complexity to the design and implementation of a program. Care must be taken to define the abstract class and its pure virtual functions correctly, ensuring that the contract is well-defined and useful for derived classes. Poorly designed abstract classes may lead to confusion or difficulty in implementing derived classes.
- Requires implementation in derived classes: Derived classes must provide implementations for all pure virtual functions declared in the abstract class. This can be seen as an extra burden when designing and implementing derived classes, as they need to fulfill the contract defined by the abstract class.
Overall, the advantages of using abstract classes, such as providing a common interface, promoting code reusability, and enabling polymorphism, often outweigh the disadvantages. However, it's important to carefully design and use abstract classes based on the specific requirements and structure of your program.
Note that a class becomes abstract when it contains at least one pure virtual function, even if it also has other non-pure virtual functions or member variables.