Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check for derived type (C++)

How do I check at runtime if an object is of type ClassA or of derived type ClassB? In one case I have to handle both instances separately

ClassA* SomeClass::doSomething ( ClassA* )
{
    if( /* parameter is of type base class */) {

    } else if { /* derived class */ ) {

    }
}

Maybe I could say that the derived class ClassB has some special capabilities. But how do I do that without changing the existing class ClassA ?

like image 854
Sney Avatar asked Mar 01 '10 10:03

Sney


2 Answers

Others have pointed out that switching on types is usually a bad idea, so I won't. If you really have to do it, you can use the typeid operator to switch on the dynamic type of an object:

ClassA* SomeClass::doSomething ( ClassA* a )
{
    if (typeid(*a) == typeid(ClassA)) {
        /* parameter is of type base class */
    } else if (typeid(*a) == typeid(ClassB)) {
        /* a specific derived class */ 
    } else {
        /* some other derived class */
    }
}

dynamic_cast is similar, but tests for convertibility, not equality:

ClassA* SomeClass::doSomething ( ClassA* a )
{
    if (ClassB *b = dynamic_cast<classB*>(a)) {
        /* parameter is, or is derived from, ClassB */
    } else {
        /* parameter is, or is derived from, ClassA but not ClassB */ 
    }
}

These only work if ClassA is polymorphic (that is, it has at least one virtual function).

like image 145
Mike Seymour Avatar answered Sep 18 '22 13:09

Mike Seymour


Use a dynamic_cast as follows:

ClassA* SomeClass::doSomething(ClassA* a)
{
    if (dynamic_cast<DerivedClass*>(a)) {
        ...
    } else if (dynamic_cast<BaseClass*>(a)) {
        ...
    }
 }

dynamic_cast<T *>(ptr) will return 0 in case ptr is not a pointer of type T, and will return a pointer of type T otherwise.

dynamic_cast can usually be avoided and is an indicator of bad design / code. If you can avoid it, try to do so, as it requires RTTI in your final executable.

like image 25
Ton van den Heuvel Avatar answered Sep 18 '22 13:09

Ton van den Heuvel