#include <cstdlib>
#include <typeinfo>
#include <ctime>
#include <iostream>
#include <list>

class Animal
{
public:
    virtual ~Animal() = 0 ;
};

Animal::~Animal() {}

class Cat : public Animal
{
};

class Dog : public Animal
{
};

typedef std::list<Animal*> list_type;

void displayTypes(list_type::iterator beg, list_type::iterator end)
{
    while (beg != end)
    {
        Animal* value = *beg++;

        if (typeid(*value) == typeid(Cat))
            std::cout << "Cat";
        else if (typeid(*value) == typeid(Dog))
            std::cout << "Dog";
        else if (typeid(*value) == typeid(Animal))
            std::cout << "Animal";          // This should never happen!
        else
            std::cout << "Unknown";

        std::cout << '\n';
    }
}

int main()
{
    std::srand(std::time(0));

    list_type list;

    for (unsigned i = 0; i < 10; ++i)
        list.push_back((rand() % 2 ? (Animal*)new Cat : (Animal*)new Dog));

    displayTypes(std::begin(list), std::end(list));

    while (!list.empty())
    {
        delete list.back();
        list.pop_back();
    }
}