Passing a function pointer of a class member?

Started by
7 comments, last by bzroom 20 years, 1 month ago
Heres what im trying to do

class c2
{
  void (*callback)(void);
  void SetCallBack(void (*func)(void));
};

class c1
{
   c2 C;

   void Callback(void);
   void Setup();
};

void c1::Setup()
{
   C->SetCallBack(Callback);
}
It doesn''t like it, it says: C2664 c1::Setup : cannot convert paramter 1 from ''void (void'' to ''void (_decl *)(void)'' What am I doing wrong, I''ve tried, this::CallBack, &CallBack, nothing works. This is the same problem I had when I classed up my window code, I had to leave the callback outside the class and just have one global window instance that the call back used, that is not going to be acceptable here. (I just typed this all in here, its not copied from my code so please dont correct irrelivant syntax errors)
Advertisement
The problem is member functions have an implicit parameter, the this pointer.

Try looking at boost::bind or in your case stl::bind1st should be sufficient for your purposes, so pass std::bind1st(&c1::Callback, this) as the parameter(I think that''s the correct syntax.

James
Look here The problem is that the SetCallback function takes a pointer to a void Function (void), but this cannot be a member function, like the callback in your example. On that site you can find more detailed information on how function pointers work.

->James

error c2805 _fn2::second_argument_Type connot form a qualified name


error c2039 second_argument_type is not a member of operator ''global namespace


(I included < functional >)

[edited by - honayboyz on March 4, 2004 9:18:21 AM]
Actually, looking it up in the docs you can't use bind1st sa this is used to convert a binary function into a unary one. Hence the errors - its trying to determine what the type of the parameter is.

Looks like you'll have to look into using boost, if you really have to do it this way. Change the function pointer to a boost::function object and then use boost::bind to pass the member function. Read the docs at Boost.org to get plenty of examples of using both bind and function, it takes a bit of understanding, but I think its worth it.

James

[edited by - jamessharpe on March 4, 2004 12:47:49 PM]
I had the same problem, and I think I had to make the member functions that I was trying to pass, as either static, or constant.
Pointer-to-(nonstatic)-member redux:
class Class{public:   void MemberFunction(int);   int MemberVariable;};void (Class::*PointerToMemberFunction)(int);int Class::*PointerToMemberVariable;PointerToMemberFunction = &Class::MemberFunction;PointerToMemberVariable = &Class::MemberVariable;Class Object;Class* Pointer = new Class;int a = Object.*PointerToMemberVariable;int b = Pointer->*PointerToMemberVariable;(Object.*PointerToMemberFunction)(10);(Pointer->*PointerToMemberFunction)(10);


These are the only operations allowed. In particular, bound pointers to members (the expressions obj.*pmember and ptr->*pmember) cannot be manipulated in any way: you cannot store a "callback" associated with a particular object. The object must be passed at the precise moment you use the pointer to member.

There isn''t any way you can treat a pointer-to-member as an ordinary function pointer either (e.g. to pass to an existing API). Don''t even try, it won''t work.

If you have control of the callback system design, then boost::function and boost::bind are a good choice.

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” — Brian W. Kernighan (C programming language co-inventor)
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

I figured out a way around it.

Since all my classes are derived from a single base class, I just added a virtual CallBack function to it and i just pass the other class a pointer to the first class and it just calls its callback function.

Thanks for the help.
Or you could have just templated the code calling the callback and used memfun. :D

This topic is closed to new replies.

Advertisement