#include <iostream>
using namespace std;
// Abstract class Shape
class Shape {
public:
virtual float calculateArea() = 0; // Pure virtual function
};
// Derived class Circle
class Circle : public Shape {
private:
float radius;
public:
Circle(float r) : radius(r) {}
float calculateArea() override {
return 3.14 * radius * radius;
}
};
// Derived class Rectangle
class Rectangle : public Shape {
private:
float length, width;
public:
Rectangle(float l, float w) : length(l), width(w) {}
float calculateArea() override {
return length * width;
}
};
int main() {
Shape* shapes[2]; // Array to hold Shape pointers
shapes[0] = new Circle(5);
shapes[1] = new Rectangle(4, 6);
for (Shape* shape : shapes) {
cout << “Area of shape: ” << shape->calculateArea() << endl;
}
// Clean up memory
for (Shape* shape : shapes) {
delete shape;
}
return 0;
}
Output:
Area of shape: 78.5
Area of shape: 24
Here’s a step-by-step explanation of the code:
1. Header and Namespace:
- #include <iostream>: Includes the iostream header for input/output operations.
- using namespace std;: Brings the std namespace into scope for convenient use of elements like cout, cin, and endl.
2. Abstract Class Shape:
- class Shape { … }: Defines an abstract class named Shape, representing general shapes.
- public: virtual float calculateArea() = 0;: Declares a pure virtual function named calculateArea(), making the class abstract.
3. Derived Classes Circle and Rectangle:
- class Circle : public Shape { … }: Derived class representing circles, inheriting from Shape.
- private: float radius;: Private member to store the radius.
- public: Circle(float r) : radius(r) {}: Constructor to initialize the radius.
- float calculateArea() override { … };: Overrides the calculateArea() function to implement area calculation for circles.
- class Rectangle : public Shape { … }: Derived class representing rectangles, also inheriting from Shape.
- private: float length, width;: Private members to store length and width.
- public: Rectangle(float l, float w) : length(l), width(w) {}: Constructor to initialize length and width.
- float calculateArea() override { … };: Overrides the calculateArea() function to implement area calculation for rectangles.
4. Main Function:
- int main() { … }: The program’s entry point.
- Shape shapes[2];*: Declares an array to hold Shape pointers.
- shapes[0] = new Circle(5);: Creates a Circle object and stores its address in the first array element.
- shapes[1] = new Rectangle(4, 6);: Creates a Rectangle object and stores its address in the second array element.
- for (Shape shape : shapes) { … }*: Iterates through the shapes array.
- cout << “Area of shape: ” << shape->calculateArea() << endl;: Calls the calculateArea() function through the Shape pointer, which dynamically dispatches to the appropriate derived class’s implementation.
- // Clean up memory: Deallocates the dynamically allocated objects to prevent memory leaks.
5. Key Points:
- Abstract Classes: Abstract classes cannot be instantiated directly, serving as blueprints for derived classes.
- Pure Virtual Functions: A class with at least one pure virtual function becomes abstract.
- Polymorphism: The ability to treat objects of different classes similarly through their common base class.
- Dynamic Dispatch: The runtime mechanism that determines which implementation of a virtual function to call based on the object’s actual type.
- Output: The program’s output will be:
Area of shape: 78.5
Area of shape: 24