Search code examples
c++runtimetypechecking

Efficient run-time type checking in C++


I've two class named 'Expression' and 'BinExp' as following codes:

class Expression
{
public:
    virtual BinExp* IsBinaryExp() { return NULL; }
};
class BinExp : public Expression
{
public:
    virtual BinExp* IsBinaryExp() { return this; }
};

As example, I've a pointer variable type of Expression* but initialized as new BinExp and send as argument to a analyse function as following code:

int main()
{
    Expression* e = new BinExp;
    analyse(e);
}

Inside the analyse function, I need to know whether the e is pointer to Expression type or BinExp type. In my hand, there is three way to do this.

First:

BinExp* be = e->IsBinaryExp();
if ( be )
{
    printf("Yes, `e` is a binary expression\n");
}

Second:

BinExp* be = dynamic_cast<BinExp*>(e);
if ( be )
{
    printf("Yes, `e` is a binary expression\n");
}

And the third:

if ( typeid(*e) == typeid(BinExp) )
{
    BinExp* be = e->IsBinaryExp(); // or dynamic_cast<BinExp*>(e);
    printf("Yes, `e` is a binary expression\n");
}

But I want to know which of those ways ( or any other ) will be more efficient and effective when I need to perform the checking frequently inside a loop where performance is a matter. Any kind of suggestion I will appreciate.


Solution

  • The fastest way would be to keep a member variable , say an enum , then define in the base class a inline getter, then you can compare if the result is what you expect.

    Sample (uncompiled, some errors might occur) :

      enum eExpTypes {
            ET_UNDEFINED,
            ET_BINARY
      }
      class Expresion
      {
          protected:
                eExpTypes myType;
          public:
                Expresion(): myType(ET_UNDEFINED){};
                inline eExpTypes getType(){return myType;};
      }
    
      class BinExpresion : public Expresion
      {
         public:
                BinExpresion():myType(ET_BINARY){};
      }
    

    Performance gain :

    • you will take out two indiections : from pointer to vfptable , from vfptable to function
    • your class size will be less if the type function is the only virtual function

    Dynamic cast is usually slower then making your own type check mechanism, so in case of your 3 examples the first one should be the fastest.