Home » Community » Forums » General Programming » function pointer to a member function of a class
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

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
Post New Topic  Post Reply 
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


 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Does your T instance still exist by the time you try to call its member function?

BlogFacebook

 User Rating: 1976   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

ya.

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

thanks!



 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

oops, forgot to post the link

http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/2793a64f-ec09-495c-b995-4f5b98a26321/

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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.

 User Rating: 918   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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?


my blog

 User Rating: 1645   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Makaan, I will try your solution, thanks!

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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]

 User Rating: 918   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: