Question: I haven't done C++ in at least 7 years and am suddenly knee deep in a C++ project. I would like some guidance with the following:

I have a class called Animal, and I have 3 classes that inherit from Animal: Cat, Dog and Bird. I have created a list object and am using it to store type Animal.

This list can contain Cats Dogs and Birds, when I am iterating through this list of Animals, I would like to know the immediate type of each Animal (whether it's a Cat, Dog or Bird).

When I say `typeid(animal).name();` it gives me Animal, which is true, but I would like to know what kind of Animal.

Any ideas?? Should I use enums??

Answer: 
Depending on the concrete code `typeid` returns different things. Additionally `name()` can return anything (including making the first letter uppercase or removing \*), it is only for debuging. Now I have a few different posible answers what `typeid(animal).name()` can return.

Version 1 `animal` is a class name:

```
struct animal {
    virtual ~animal() {}
};

struct dog 
    : animal
{};

struct cat
    : animal
{};

struct bird
    : animal
{};

int main() {
    std::cout << typeid(animal).name() << std::endl; // animal
    return 0;
}

```

Version 2 `animal` is a typedef to `Animal`:

```
struct Animal {
};

struct Dog 
    : Animal
{};

struct Cat
    : Animal
{};

struct Bird
    : Animal
{};

int main() {
    typedef Animal animal;
    std::cout << typeid(animal).name() << std::endl; // Animal
    return 0;
}

```

Vesion 3 `animal` is a pointer:

```
struct Animal {
};

struct Dog 
    : Animal
{};

struct Cat
    : Animal
{};

struct Bird
    : Animal
{};

int main() {
    Dog d;
    Animal* animal=&d;
    std::cout << typeid(animal).name() << std::endl; // Animal*
    return 0;
}

```

Version 4 `animal` is a object:

```
struct Animal {
};

struct Dog 
    : Animal
{};

struct Cat
    : Animal
{};

struct Bird
    : Animal
{};

int main() {
    Animal animal;
    std::cout << typeid(animal).name() << std::endl; // Animal
    return 0;
}

```

Version 6 `animal` is a reference to a **non polymorphic** objcet:

```
struct Animal {
};

struct Dog 
    : Animal
{};

struct Cat
    : Animal
{};

struct Bird
    : Animal
{};

int main() {
    Dog d;
    Animal& animal=d;
    std::cout << typeid(animal).name() << std::endl; // Animal
    return 0;
}

```

and version 7 `animal` is a reference to a **polymorphic** object:

```
struct Animal {
  ~virtual Animal() {}
};

struct Dog 
    : Animal
{};

struct Cat
    : Animal
{};

struct Bird
    : Animal
{};

int main() {
    Dog d;
    Animal& animal=d;
    std::cout << typeid(animal).name() << std::endl; //Dog
    return 0;
}

```

As others have written it's better not to rely on `name()`. But without some code it's not easy to say what's correct.
Implement a function name() in each subclass.