Jump to content
  • Advertisement
Sign in to follow this  
baumchen

function pointer to a member function of a class

This topic is 3297 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
oops, forgot to post the link

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!