type_identification


Concept: Type Identification

Type identification in C++ is a crucial feature that allows programmers to determine and work with the types of objects at runtime. This capability is particularly useful in scenarios involving polymorphism, generic programming, and debugging.

Key Characteristics

1. Basic Usage with Fundamental Types

#include <iostream>
#include <typeinfo>

int main() {
    int i = 5;
    double d = 3.14;
    char c = 'A';

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

    return 0;
}

Explanation

Example 2: Type Identification with Polymorphic Classes

#include <iostream>
#include <typeinfo>

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

class Derived : public Base {
};

void printType(const Base& obj) {
    std::cout << "Type: " << typeid(obj).name() << std::endl;
}

int main() {
    Base b;
    Derived d;

    printType(b);
    printType(d);

    Base* ptr = &d;
    std::cout << "Type of *ptr: " << typeid(*ptr).name() << std::endl;

    return 0;
}

Explanation

Example 3: Type Comparison

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

template<typename T>
void checkType(const T& value) {
    if (typeid(value) == typeid(int)) {
        std::cout << "It's an integer!" << std::endl;
    } else if (typeid(value) == typeid(std::string)) {
        std::cout << "It's a string!" << std::endl;
    } else {
        std::cout << "It's something else." << std::endl;
    }
}

int main() {
    int i = 42;
    std::string s = "Hello";
    std::vector<int> v = {1, 2, 3};

    checkType(i);
    checkType(s);
    checkType(v);

    return 0;
}

Explanation

Example 4: Exception Handling with Type Identification

#include <iostream>
#include <typeinfo>
#include <stdexcept>

class CustomException : public std::exception {
public:
    const char* what() const noexcept override {
        return "Custom Exception";
    }
};

void riskyFunction(int x) {
    if (x < 0) {
        throw std::runtime_error("Negative number");
    } else if (x == 0) {
        throw CustomException();
    }
    std::cout << "x is positive" << std::endl;
}

int main() {
    try {
        riskyFunction(-1);
    } catch (const std::exception& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
        std::cout << "Exception type: " << typeid(e).name() << std::endl;
    }

    try {
        riskyFunction(0);
    } catch (const std::exception& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
        std::cout << "Exception type: " << typeid(e).name() << std::endl;
    }

    return 0;
}

Explanation

Additional Considerations

  1. Performance: RTTI can have a small runtime overhead, so it should be used judiciously in performance-critical code.

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

  3. Use with Templates: typeid can be particularly useful in template metaprogramming for type-based decision making.

  4. Limitations: typeid doesn't work with non-polymorphic types through pointers or references to a base class.

Summary

Type identification in C++ provides a powerful mechanism for runtime type checking and manipulation. The typeid operator, along with the <typeinfo> header, enables developers to query and compare types at runtime. This feature is particularly useful in scenarios involving polymorphism, generic programming, and exception handling.

Key points to remember:

  1. typeid returns a const std::type_info& object.
  2. For polymorphic types, typeid determines the type of the most derived object.
  3. Type comparison can be done using typeid(a) == typeid(b).
  4. RTTI must be enabled (it usually is by default) for typeid to work correctly with polymorphic types.
  5. While powerful, type identification should be used judiciously due to potential performance implications.

By leveraging type identification, C++ programmers can write more flexible, type-safe, and robust code, especially when dealing with complex class hierarchies or generic programming paradigms.

Previous Page | Course Schedule | Course Content