#include <iostream>
#include <string>
using namespace std;
class Animal {
protected:
string name;
int age;
public:
Animal(string n, int a) : name(n), age(a) {}
virtual void makeSound() = 0;
virtual void eat() {
cout << "The animal is eating." << endl;
}
virtual void sleep() {
cout << name << " is sleeping." << endl;
}
virtual ~Animal() {}
};
class Mammal : public Animal {
protected:
bool isSleeping;
public:
Mammal(string n, int a)
: Animal(n, a), isSleeping(false) {}
bool canAct() {
return !isSleeping;
}
void wakeUp() {
isSleeping = false;
cout << name << " woke up." << endl;
}
void makeSound() override {
if (!canAct()) return;
cout << "Generic mammal sound." << endl;
}
void eat() override {
if (!canAct()) return;
cout << "The mammal is eating." << endl;
}
void sleep() override {
cout << name << " is sleeping." << endl;
isSleeping = true;
}
};
class Dog : public Mammal {
private:
bool isTailWagging;
public:
Dog(string n, int a)
: Mammal(n, a), isTailWagging(false) {}
void makeSound() override {
if (!canAct()) return;
cout << "Woof!" << endl;
}
void eat() override {
if (!canAct()) return;
cout << "The dog is eating." << endl;
}
void sleep() override {
Mammal::sleep();
}
void fetch() {
if (!canAct()) return;
cout << "The dog is fetching." << endl;
}
void wagTail() {
if (!canAct()) {
cout << "The dog can't wag its tail because it's sleeping."
<< endl;
return;
}
isTailWagging = true;
cout << "The dog is wagging its tail." << endl;
}
};
class Cat : public Mammal {
private:
int numberOfLives;
public:
Cat(string n, int a)
: Mammal(n, a), numberOfLives(9) {}
void makeSound() override {
if (!canAct()) return;
cout << "Meow!" << endl;
}
void eat() override {
if (!canAct()) return;
cout << "The cat is eating." << endl;
}
void sleep() override {
Mammal::sleep();
}
};
class Tail : public Dog {
public:
Tail(string n, int a)
: Dog(n, a) {}
};
int main() {
Dog d("Fido", 3);
Cat c("Fluffy", 5);
Dog d1("Barky", 3);
Mammal* arr[] = { &d, &c, &d1 };
cout << "Sounds:" << endl;
for (int i = 0; i < 3; i++)
arr[i]->makeSound();
cout << "\nEating:" << endl;
for (int i = 0; i < 3; i++)
arr[i]->eat();
cout << "\nSleeping:" << endl;
for (int i = 0; i < 3; i++)
arr[i]->sleep();
cout << "\nTrying to make sounds while sleeping:" << endl;
for (int i = 0; i < 3; i++)
arr[i]->makeSound();
cout << "\nTrying to eat while sleeping:" << endl;
for (int i = 0; i < 3; i++)
arr[i]->eat();
cout << "\nTrying to wag tails:" << endl;
for (int i = 0; i < 3; i++) {
Dog* dog = dynamic_cast<Dog*>(arr[i]);
if (dog)
dog->wagTail();
}
cout << "\nWake up one dog:" << endl;
d.wakeUp();
d.wagTail();
cout << "\nTail object:" << endl;
Tail t("Taily", 2);
t.makeSound();
return 0;
}