Type checking in C++
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!
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
You can use typeid().
if (typeid(childObject) == typeid(ChildType)) {
}
If this returns true, then you know it's the child class.