#include <iostream>

// base class
class Animal {
public:
	virtual void talk() = 0; // we don't provide any implementation here
	virtual ~Animal() {} // destructor must be virtual
};

// derived classes
class Cat: public Animal {
public:
	Cat()
	{
		std::cout << "I want Whiskas!" << std::endl;
	}

	~Cat()
	{
		std::cout << "Meooooooouuuchhh!" << std::endl;
	}

	void talk()
	{
		std::cout << "Meow!" << std::endl;
	}
};

class Dog: public Animal {
public:
	Dog()
	{
		std::cout << "I want Pedigree!" << std::endl;
	}

	~Dog()
	{
		std::cout << "Woooooaaaaaaaaaargghhhh!" << std::endl;
	}

	void talk()
	{
		std::cout << "Woof!" << std::endl;
	}
};

class Human: public Animal {
public:
	Human()
	{
		std::cout << "I want pizza!" << std::endl;
	}

	~Human()
	{
		std::cout << "Yahooooowl!" << std::endl;
	}

	void talk()
	{
		std::cout << "Hello!" << std::endl;
	}
};

int main()
{
	Animal *zoo[3];

	zoo[0] = new Cat;
	zoo[1] = new Dog;
	zoo[2] = new Human;

	zoo[0]->talk();
	zoo[1]->talk();
	zoo[2]->talk();

	delete zoo[0];
	delete zoo[1];
	delete zoo[2];
}
