#include <iostream>
#include <memory>

class Animals
{
public:
	virtual void Display() = 0;
	virtual ~Animals() = default;
};

class Dog : public Animals
{
	void Display() override
	{
		std::cout << "This is Dog!" << std::endl;
	}
};

class Cat : public Animals
{
	void Display() override
	{
		std::cout << "This is Cat!" << std::endl;
	}
};

class Goat : public Animals
{
	void Display() override
	{
		std::cout << "This is Goat!" << std::endl;
	}
};

int main()
{
	Animals* animal = new Dog;
	animal->Display();
	delete animal; // delete at some point to avoid memory leak as Dog is allocated on the heap

	Cat cat;
	animal = &cat;
	animal->Display(); // no delete needed, as Cat is allocated on the stack and will cleared when goes out of scope

	std::unique_ptr<Animals> animal2 = std::make_unique<Goat>();
	animal2->Display(); // no delete needed, Goat is allocated on the heap but will be cleared when goes out of scope

	return 0;
}