typeinfo


Header: <typeinfo>

The <typeinfo> header is part of the C++ Standard Library that provides runtime type identification (RTTI) support. It allows programs to obtain information about object types at runtime. This header is particularly useful when working with polymorphic types and when you need to determine the type of an object dynamically.

Key Characteristics

Example 1: Basic Usage of typeid and type_info

#include <iostream>
#include <typeinfo>
#include <string>

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {};

int main() {
    int i = 5;
    double d = 3.14;
    std::string s = "Hello";
    Base* b = new Derived();

    std::cout << "Type of i: " << typeid(i).name() << std::endl;
    std::cout << "Type of d: " << typeid(d).name() << std::endl;
    std::cout << "Type of s: " << typeid(s).name() << std::endl;
    std::cout << "Type of *b: " << typeid(*b).name() << std::endl;

    delete b;
    return 0;
}

Explanation:

Example 2: Type Comparison Using type_info

#include <iostream>
#include <typeinfo>

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

class Dog : public Animal {};
class Cat : public Animal {};

void identifyAnimal(Animal* animal) {
    if (typeid(*animal) == typeid(Dog)) {
        std::cout << "This animal is a Dog" << std::endl;
    } else if (typeid(*animal) == typeid(Cat)) {
        std::cout << "This animal is a Cat" << std::endl;
    } else {
        std::cout << "Unknown animal type" << std::endl;
    }
}

int main() {
    Animal* dog = new Dog();
    Animal* cat = new Cat();
    Animal* generic_animal = new Animal();

    identifyAnimal(dog);
    identifyAnimal(cat);
    identifyAnimal(generic_animal);

    delete dog;
    delete cat;
    delete generic_animal;

    return 0;
}

Explanation:

Example 3: Handling bad_typeid Exception

#include <iostream>
#include <typeinfo>

class Base {
public:
    virtual ~Base() {}
};

int main() {
    try {
        Base* ptr = nullptr;
        std::cout << typeid(*ptr).name() << std::endl;
    } catch (const std::bad_typeid& e) {
        std::cout << "Caught bad_typeid exception: " << e.what() << std::endl;
    }

    return 0;
}

Explanation:

Example 4: Using type_info::before() for Type Ordering

#include <iostream>
#include <typeinfo>
#include <vector>
#include <algorithm>

class A {};
class B : public A {};
class C {};

bool compareTypes(const std::type_info* a, const std::type_info* b) {
    return a->before(*b);
}

int main() {
    std::vector<const std::type_info*> types = {
        &typeid(int),
        &typeid(double),
        &typeid(A),
        &typeid(B),
        &typeid(C),
        &typeid(std::string)
    };

    std::sort(types.begin(), types.end(), compareTypes);

    for (const auto& type : types) {
        std::cout << type->name() << std::endl;
    }

    return 0;
}

Explanation:

Example 5: RTTI with Virtual Inheritance

#include <iostream>
#include <typeinfo>

class Base {
public:
    virtual ~Base() {}
};

class DerivedA : virtual public Base {};
class DerivedB : virtual public Base {};
class MostDerived : public DerivedA, public DerivedB {};

void printType(Base* ptr) {
    std::cout << "Actual type: " << typeid(*ptr).name() << std::endl;
}

int main() {
    Base* b1 = new DerivedA();
    Base* b2 = new DerivedB();
    Base* b3 = new MostDerived();

    printType(b1);
    printType(b2);
    printType(b3);

    delete b1;
    delete b2;
    delete b3;

    return 0;
}

Explanation:

Additional Considerations

  1. Performance Impact: RTTI can have a performance cost, especially in large hierarchies. Some compilers allow disabling RTTI for performance-critical code.

  2. Compiler Differences: The string returned by type_info::name() is implementation-defined and may vary between compilers.

  3. Use with Caution: Overreliance on RTTI can lead to brittle designs. It's often better to use virtual functions for polymorphic behavior.

  4. Cross-Module Issues: RTTI might not work correctly across module boundaries in some implementations.

  5. Memory Management: Remember that typeid doesn't affect the lifetime of its operands. Proper memory management is still necessary.

Summary

The <typeinfo> header in C++ provides runtime type identification capabilities:

RTTI, provided through <typeinfo>, is a powerful feature that allows C++ programs to make decisions based on the types of objects at runtime. This is particularly useful in scenarios involving polymorphism, where the exact type of an object may not be known at compile time.

However, it's important to use RTTI judiciously. Overuse can lead to code that is hard to maintain and potentially less efficient. In many cases, proper use of virtual functions and polymorphism can provide better design solutions than relying on explicit type checking.

When used appropriately, the facilities provided by <typeinfo> can be valuable tools for creating flexible and robust C++ programs, especially when dealing with complex class hierarchies or when implementing generic programming techniques that need to adapt to different types at runtime.

Related

Previous Page | Course Schedule | Course Content