I'm using the following functor class:
class AFunctorBase{public: virtual void call()=0; virtual ~AFunctorBase(){}};template<typename T>class AFunctor : public AFunctorBase{public: AFunctor(T* pObject, void(T::*pFunc)()) { m_pObject = pObject; m_pFunc = pFunc; } virtual ~AFunctor(){} virtual void call() { (*m_pObject.*m_pFunc)(); }private: void(T::*m_pFunc)(); T* m_pObject;};
Say I have two other classes:
class A{public: virtual void do_crazy_thangs() { std::cout<<"Class A"<<std::endl; void CreateFunctor();private: AFunctor* m_pFunctor;};void A::CreateFunctor(){ m_pFunctor = new AFunctor<A>(this, &A::do_crazy_thangs());}class B : public A{public: virtual void do_crazy_thangs() { std::cout<<"Class B"<<std::endl;};
Then class B calls CreateFunctor();
CreateFunctor();// andm_pFunctor->call();
This prints "Class B".
Mind you the actual context of the problem was much more complicated, but I spent a pretty good chunk of time trying to figure out how I was going to achieve derived functionality in do_crazy_thangs() when in order to create a functor I have to actually specify the class type to which the function being called belongs, and the address of that function. I thought that it would call that precise function regardless of inheritance. It does not, "Class B" prints. The only way I could have possibly been happier about this would have been if I had just tried it 2 hours earlier instead of trying to figure out how to accommodate a situation that didn't actually exist.
Still, I don't fully understand why it works. Is making a function call via a functor no different than making the call via somePointerToObject->do_crazy_thangs(); ? Does the compiler look at the function in some lookup table the same way it would ordinarily and realize that it is virtual and there is a derived function? Is it specifically because I pass the 'this' pointer to create the Functor? If that is the case what purpose does the functor really have for the class of the object?
Sorry if the question is confusing, but it's bugging me.
Thanks.
[Edited by - Aztral on September 30, 2010 2:29:46 AM]