• Advertisement
Sign in to follow this  

function pointer to a member function of a class

This topic is 3031 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