#include <iostream>
using namespace std;
// Base class
class Animal {
public:
virtual void speak() {
cout << “Animal sound” << endl;
}
};
// Derived classes
class Dog : public Animal {
public:
void speak() override {
cout << “Woof!” << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << “Meow!” << endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->speak(); // Output: Woof!
animal2->speak(); // Output: Meow!
delete animal1;
delete animal2;
return 0;
}
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. Base Class Animal:
- class Animal { … }: Defines a base class named Animal to represent general animals.
- public: virtual void speak() { … };: Declares a virtual function named speak() that outputs a generic animal sound.
3. Derived Classes Dog and Cat:
- class Dog : public Animal { … }: Derived class representing dogs, inheriting from Animal.
- void speak() override { … };: Overrides the speak() function to output “Woof!”.
- class Cat : public Animal { … }: Derived class representing cats, also inheriting from Animal.
- void speak() override { … };: Overrides the speak() function to output “Meow!”.
4. Main Function:
- int main() { … }: The program’s entry point.
- Animal animal1 = new Dog();*: Creates a pointer to an Animal, but dynamically allocates a Dog object.
- Animal animal2 = new Cat();*: Similarly, creates a pointer to Animal pointing to a Cat object.
- animal1->speak();: Calls the speak() function on the Dog object through the Animal pointer.
- animal2->speak();: Calls the speak() function on the Cat object through the Animal pointer.
- delete animal1; delete animal2;: Proper memory management to deallocate the objects.
- return 0;: Indicates successful program termination.
5. Key Points:
- Virtual Functions: Virtual functions allow for runtime polymorphism, where the actual function called depends on the object’s type, not the pointer’s type.
- Dynamic Polymorphism: This enables dynamic behavior based on the object’s actual type, even when accessed through a base class pointer.
- Override Keyword: The override keyword explicitly indicates that a derived class function is intended to override a virtual function in the base class.
- Output: The program’s output will be:
Woof!
Meow!