Skip to main content
GameDev.net gamedev.net
🔒 Locked

function pointer to a member function of a class

Started by baumchen Nov 2, 2009 at 10:30 PM 6 replies 900+ views
Original Post
baumchen
baumchen
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 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
ToohrVyk
Does your T instance still exist by the time you try to call its member function?
baumchen
baumchen
ya.

by the way, someone gave me a link, and suggested using /vmg, and it worked.

thanks!

baumchen
baumchen
oops, forgot to post the link

http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/2793a64f-ec09-495c-b995-4f5b98a26321/
Makaan
Makaan
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
Codeka
Quote:
Original post by baumchen
oops, forgot to post the link

http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/2793a64f-ec09-495c-b995-4f5b98a26321/
Wow, I wonder how boost::function does it without that compiler switch?
baumchen
baumchen
Makaan, I will try your solution, thanks!
Makaan
Makaan
Hello
I found a small error in the code in function callback() the correct code is:
return new __CallBack(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]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.