When implementing polymorphic behavior in C++ one can either use a pure virtual method or one can use function pointers (or functors). For example an asynchronous callback can be implemented by:
class Callback { public: Callback(); ~Callback(); void go(); protected: virtual void doGo() = 0; }; //Constructor and Destructor void Callback::go() { doGo(); }
So to use the callback here, you would need to override the doGo() method to call whatever function you want
typedef void (CallbackFunction*)(void*) class Callback { public: Callback(CallbackFunction* func, void* param); ~Callback(); void go(); private: CallbackFunction* iFunc; void* iParam; }; Callback::Callback(CallbackFunction* func, void* param) : iFunc(func), iParam(param) {} //Destructor void go() { (*iFunc)(iParam); }
To use the callback method here you will need to create a function pointer to be called by the Callback object.
[This was added to the question by me (Andreas); it wasn't written by the original poster]
template <typename T> class Callback { public: Callback() {} ~Callback() {} void go() { T t; t(); } }; class CallbackTest { public: void operator()() { cout << "Test"; } }; int main() { Callback<CallbackTest> test; test.go(); }
What are the advantages and disadvantages of each implementation?
A virtual function is a member function of base class which can be redefined by derived class. A pure virtual function is a member function of base class whose only declaration is provided in base class and should be defined in derived class otherwise derived class also becomes abstract.
Virtual functions ensure that the correct function is called for an object, regardless of the type of reference (or pointer) used for function call. Functions are declared with a virtual keyword in base class.
It is declared using the virtual keyword. It is used to tell the compiler to perform dynamic linkage or late binding on the function. There is a necessity to use the single pointer to refer to all the objects of the different classes. So, we create the pointer to the base class that refers to all the derived objects.
A function pointer, also called a subroutine pointer or procedure pointer, is a pointer that points to a function. As opposed to referencing a data value, a function pointer points to executable code within memory.
Approach 1 (Virtual Function)
Approach 2 (Class with Function Pointer)
Approach 3 (Class calling T functor)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With