|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| function pointer to a member function of a class |
|
![]() baumchen Member since: 12/12/2008 |
||||
|
|
||||
| Hi, all I need to write a class who offers a general function so that once the function is called, some function of another class will be called eventually. I plan to use such a template class template <class T, class S> struct Port { typedef int (T::*FuncPointer)(const S*); FuncPointer functionPointer; T* classPointer; Port(T* classPtr, FuncPointer funcPtr) { classPointer = classPtr; functionPointer = funcPtr; } int Write(const S* data) { return (classPointer->*functionPointer)(data); } }; my question is, will this work in general? I tried it on two classes, and it worked. however, back to my vc2003 project (which is much more complicate), if failed. functionPointer's offset at constructor is 4 (from class pointer), but it somehow changed to 8 when Write gets called. plus, it never gets correct offset in vc2003's watch window. anyone has a clue? I will try to see whether I can replicate this problem on a simple project. thanks! baum |
||||
|
||||
![]() ToohrVyk Member since: 9/12/2002 From: Paris, France |
||||
|
|
||||
| Does your T instance still exist by the time you try to call its member function? Blog — Facebook |
||||
|
||||
![]() baumchen Member since: 12/12/2008 |
||||
|
|
||||
| ya. by the way, someone gave me a link, and suggested using /vmg, and it worked. thanks! |
||||
|
||||
![]() baumchen Member since: 12/12/2008 |
||||
|
|
||||
| oops, forgot to post the link http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/2793a64f-ec09-495c-b995-4f5b98a26321/ |
||||
|
||||
![]() Makaan Member since: 3/20/2008 From: Cluj-Napoca, Romania |
||||
|
|
||||
Callback.h:class __iCallback { private: inline __iCallback() { RefCount = 0; } private: virtual void __CallMethod()=0; private: unsigned int RefCount; private: friend class Callback; template <class T> friend class __CallBack; }; class Callback { public: Callback(); ~Callback(); Callback(const Callback &other); Callback(__iCallback *prv); public: void operator = (const Callback &other); void operator = (__iCallback *prv); void Detach(); inline bool isEmpty()const { return (method == 0); } public: inline void exec() { if(method) method->__CallMethod(); } inline void operator()() { if(method) method->__CallMethod(); } //------------------------------------------------ private: __iCallback *method; }; //------------------------------------------------ //------------------------------------------------ template <class T> class __CallBack : public __iCallback { private: typedef void (T::*CallProcedure)(); public: __CallBack(T * s ,void (T::*m)()) :source(s),method(m) {} public: virtual void __CallMethod() { (source->*method)(); } private: T * source; CallProcedure method; private: friend class Callback; }; //---------------------------------- template <typename OBJ> inline __iCallback* callback(OBJ * what, void(OBJ::*method)()) { return new __CallBack<OBJ>(what,&method); } Callback.cpp Callback::Callback() : method(0) { } Callback::~Callback() { if(method) { method->RefCount--; if(method->RefCount==0) delete method; } } Callback::Callback(const Callback& other) :method(other.method) { method->RefCount++; } Callback::Callback(__iCallback* prv) { method = prv; method->RefCount++; } void Callback::Detach() { if(method) { method->RefCount--; if(method->RefCount==0) delete method; } method = 0; } //--------------------------------------------- void Callback::operator =(const Callback& other) { if(method) { method->RefCount--; if(method->RefCount==0) delete method; } method = other.method; method->RefCount++; } void Callback::operator = (__iCallback* prv) { if(method) { method->RefCount--; if(method->RefCount==0) delete method; } method = prv; method->RefCount++; } Usage: Callback m;// this object will call any function from any object m = callback(InstanceOfObject,&TypeOfObject::MethodToCall);// this is how you associate m with an instance and a method m() or m.exec()// is how you call the method, equivalent with InstanceOfObject->MethodToCall(); It is easy to modify this so that you can call methods with arguments. The basic structure of this is: Callback is a class that holds and interface (__iCallback) the interface has a virtual memeber function that will actually make the call for you. When you associate a Callback with a member function you use callback. What happens here is the following: The class __CallBack is a template that implements __iCallback and hold information regarding the instance of the object , type and pointer to a memeber function. The implementation of the method virtual void __CallMethod() will call the method for you. The new __CallBack is cast to a the interface so that you can have anywhere access. I hope this helped and you got the idea :) Raxvan. |
||||
|
||||
![]() Codeka Member since: 10/19/2008 From: Sydney, Australia |
||||
|
|
||||
Quote:Wow, I wonder how boost::function does it without that compiler switch? my blog |
||||
|
||||
![]() baumchen Member since: 12/12/2008 |
||||
|
|
||||
| Makaan, I will try your solution, thanks! |
||||
|
||||
![]() Makaan Member since: 3/20/2008 From: Cluj-Napoca, Romania |
||||
|
|
||||
| Hello I found a small error in the code in function callback() the correct code is: return new __CallBack<OBJ>(what,method); instead of `&method` Note: as you can see you allocate some memory there. You don't have to worry about deleting that memory.The class Callback will do that for you by using reference counting. Raxvan. [Edited by - Makaan on November 4, 2009 1:40:05 AM] |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|