Virtual Methods or Function Pointers

Approach 1 (Virtual Function)

  • “+” The “correct way to do it in C++
  • “-” A new class must be created per callback
  • “-” Performance-wise an additional dereference through VF-Table compared to Function Pointer. Two indirect references compared to Functor solution.

Approach 2 (Class with Function Pointer)

  • “+” Can wrap a C-style function for C++ Callback Class
  • “+” Callback function can be changed after callback object is created
  • “-” Requires an indirect call. May be slower than functor method for callbacks that can be statically computed at compile-time.

Approach 3 (Class calling T functor)

  • “+” Possibly the fastest way to do it. No indirect call overhead and may be inlined completely.
  • “-” Requires an additional Functor class to be defined.
  • “-” Requires that callback is statically declared at compile-time.

FWIW, Function Pointers are not the same as Functors. Functors (in C++) are classes that are used to provide a function call which is typically operator().

Here is an example functor as well as a template function which utilizes a functor argument:

class TFunctor
{
public:
    void operator()(const char *charstring)
    {
        printf(charstring);
    }
};

template<class T> void CallFunctor(T& functor_arg,const char *charstring)
{
    functor_arg(charstring);
};

int main()
{
    TFunctor foo;
    CallFunctor(foo,"hello world\n");
}

From a performance perspective, Virtual functions and Function Pointers both result in an indirect function call (i.e. through a register) although virtual functions require an additional load of the VFTABLE pointer prior to loading the function pointer. Using Functors (with a non-virtual call) as a callback are the highest performing method to use a parameter to template functions because they can be inlined and even if not inlined, do not generate an indirect call.

Leave a Comment