C++ equivalent of instanceof


Question

What is the preferred method to achieve the C++ equivalent of instanceof?

1
193
2/1/2009 9:32:48 AM

Accepted Answer

Try using:

if(NewType* v = dynamic_cast<NewType*>(old)) {
   // old was safely casted to NewType
   v->doSomething();
}

This requires your compiler to have rtti support enabled.

EDIT: I've had some good comments on this answer!

Every time you need to use a dynamic_cast (or instanceof) you'd better ask yourself whether it's a necessary thing. It's generally a sign of poor design.

Typical workarounds is putting the special behaviour for the class you are checking for into a virtual function on the base class or perhaps introducing something like a visitor where you can introduce specific behaviour for subclasses without changing the interface (except for adding the visitor acceptance interface of course).

As pointed out dynamic_cast doesn't come for free. A simple and consistently performing hack that handles most (but not all cases) is basically adding an enum representing all the possible types your class can have and check whether you got the right one.

if(old->getType() == BOX) {
   Box* box = static_cast<Box*>(old);
   // Do something box specific
}

This is not good oo design, but it can be a workaround and its cost is more or less only a virtual function call. It also works regardless of RTTI is enabled or not.

Note that this approach doesn't support multiple levels of inheritance so if you're not careful you might end with code looking like this:

// Here we have a SpecialBox class that inherits Box, since it has its own type
// we must check for both BOX or SPECIAL_BOX
if(old->getType() == BOX || old->getType() == SPECIAL_BOX) {
   Box* box = static_cast<Box*>(old);
   // Do something box specific
}
193
4/26/2015 8:01:12 AM

Depending on what you want to do you could do this:

template<typename Base, typename T>
inline bool instanceof(const T*) {
    return std::is_base_of<Base, T>::value;
}

Use:

if (instanceof<BaseClass>(ptr)) { ... }

However, this purely operates on the types as known by the compiler.

Edit:

This code should work for polymorphic pointers:

template<typename Base, typename T>
inline bool instanceof(const T *ptr) {
    return dynamic_cast<const Base*>(ptr) != nullptr;
}

Example: http://cpp.sh/6qir


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon