Search code examples
c++castingtypechecking

Type checking in C++


In C++, I want to know whether the actual type of the object is from the same class, not the same class or a derived one. This is similar to the following C# code:

Class Base
{
}

Class Child:Base
{
}

Base childObject = new Child();

If (childObject.GetType() == typeof(Child))
{
 // do some code
}

Thanks!


Solution

  • There are two ways that you can do this. First, you can use the typeid operator, which returns a type_info structure containing information about the type of the object. For example:

    Base* ptr = /* ... */
    if (typeid(*ptr) == typeid(DerivedType)) {
        /* ... ptr points to a DerivedType ... */
    }
    

    Notice that you have to use typeid(*ptr) and not typeid(ptr) here. If you use typeid(ptr), then you'll get back a type_info object for Base*, since the pointer has type Base* regardless of what it points at.

    An important point to note is that this will check if what ptr points at is exactly a DerivedType. If ptr is pointing at an object of a type derived from DerivedType (maybe an EvenMoreDerivedType), this code will not work correctly.

    An alternative way of checking whether you are pointing at an object of some type that is a bit more robust is to use the dynamic_cast operator. dynamic_cast performs a checked typecast at runtime that will yield a valid pointer if the cast succeeds and nullptr otherwise. For example:

    Base* ptr = /* ... */;
    auto* derived = dynamic_cast<DerivedType*>(ptr);
    if (derived) {
        /* ... points to a DerivedType ... */
    }
    

    This has the added advantage that if ptr points at something like an EvenMoreDerivedType, the cast will still succeed because EvenMoreDerivedType inherits from DerivedType.

    As a final thought, you sometimes see code like this:

    Base* ptr = /* ... */
    if (auto* derived = dynamic_cast<DerivedType*>(ptr)) {
         /* ... points to a DerivedType ... */
    }
    

    This locally-scopes the derived pointer to the body of the if statement and uses the fact that nonzero values evaluate to true in C++. I personally find this easier to read and less error-prone, but by all means go with what's easiest for you.

    Hope this helps!