Homam
Homam

Reputation: 23841

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!

Upvotes: 36

Views: 52101

Answers (3)

templatetypedef
templatetypedef

Reputation: 372784

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!

Upvotes: 75

Tim
Tim

Reputation: 9172

While DeadMG's answer is correct (I've used typeid many times), I thought I'd throw this out there for posterity. The "right" way to do this, from an Object-Oriented view is:

Class Base
{
    virtual void something() {
        // probably a no-op, but maybe some default stuff
    }
}

Class Child : public Base
{
    virtual void something() {
        // do your child-specific code here
    }
}

Base* childObject = new Child();
childObject->something();  // does the right thing

Upvotes: 12

Puppy
Puppy

Reputation: 146910

You can use typeid().

if (typeid(childObject) == typeid(ChildType)) {
}

If this returns true, then you know it's the child class.

Upvotes: 3

Related Questions