Function pointers pointing to class functions?

Started by
29 comments, last by Roof Top Pew Wee 22 years, 4 months ago
Here''s a simplified version of what I am trying to do: typedef void (*voidFunction) (); class A {public: void functionA(){} }; class B {public: voidFunction functionPointer; void setFunction(voidFunction functionToSetTo) { functionPointer = functionToSetTo; } }; int main() { A classA; B classB; classB.setFunction(&(classA.functionA)); } The error I get is: ''&'' : illegal operation on bound member function expression. Pretty much, I have a function pointer in class A and I want it to point to the function in class B. I have gotten classes (A in this case) to be able to point to functions not contained in a class, but how do I get it to point to a function inside of a class (B in this case). Thanks for any help. --Vic--
Advertisement
i dont think you need the &..

every piece of function pointer code ive ever written has never needed it. i could be wrong though.
i dont think you need the &..

every piece of function pointer code ive ever written has never needed it. i could be wrong though.
Funny, every piece of function pointer code I''ve written has needed it. I did try it without the & and here''s the error:

C2664: ''setFunction'' : cannot convert parameter 1 from ''void (void)'' to ''void (__cdecl *)(void)''

I''m pretty sure that when you pass the function, you either have to give it the address or cast it with they type I''ve defined.

--Vic--
Change

classB.setFunction(&(classA.functionA));


to

classB.setFunction(&classA::functionA);

Also there is another problem, your typedef is not a member function pointer.

It needs to be:

typedef void (classA::*voidFunction) ();

I'm in the middle of something right now so there may be more issues...I'll check over it again in a sec.

BTW You must use the & operator to get the address of a member function...

Dire Wolf
www.digitalfiends.com

Edited by - Dire.Wolf on November 9, 2001 6:25:34 PM

Edited by - Dire.Wolf on November 9, 2001 6:39:59 PM
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
For the voidFunction pointer-type to be able to hold pointers to methods you must declare it like:
  typedef void (A::*voidFunction) ();  

This becomes a pointer to a method in objects of class A. To set it you do something like:
  voidFunction funPtr;funPtr = A::functionA;  

and to later call it you must have an object of class A, and call it for that object. e.g:
  // either:A a;a.*funPtr(); // or:A * pa = new A();pa->*funPtr();  

Hope things are clearer now (and I hope I didn''t make any big mistakes )
Dire.Wolf:
Hmmm, very interesting. One note: You said to change it to
&(classA::function). This is incorrect because when using the :: (scope resolution operator I believe) you have to have a class on the left side, not an object. So the correct method would be (&(A::voidfunction)).

However, your solution sets up a few problems.

1: Just because a function is in a class rather than outside of one, does it really chage it? I mean, ovbiously it does in my case, but isn''t there a way to just have a typedef for both functions in and outside of classes? And what if I have two classes that have a void function and I want to assign one or the other depending on some condition? Do I then have to have a typedef for the function in both class A and class B?

2: Also, this solution seems to point to the general function for the class A. But what the function that you are pointing to does work with members of the specific class. Example:

class A
{public:
int x;
void functionA(){x++;}
};

Now say that you have 3 instances of class A like this:

A classA1;
A classA2;
A classA3;

When you set the function in class B equal to A::functionA, well, how would the compiler know which x to add? classA1.x, classA2.x, or classA3.x?

--Vic--
Roof Top Pew Wee,

No to set a member function you use the scope-resolution operator to access the member function:

typedef void (A::*memberFunc)();

memberFunc m = &A::SomeActualFunc;

Then to call the function you must hold an object reference and call it using the pointer to member operator:

A* a = new A;
memberFunc m = &A::SomeActualFunc;

(a->*m)();

delete a;

That is all there is to it.

Remember all you are doing is passing the address of a function. You aren't passing an instance of that function because there is no such thing.





Dire Wolf
www.digitalfiends.com

Edited by - Dire.Wolf on November 9, 2001 6:56:46 PM
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
quote:Original post by Roof Top Pew Wee
Dire.Wolf:
Hmmm, very interesting. One note: You said to change it to
&(classA::function). This is incorrect because when using the :: (scope resolution operator I believe) you have to have a class on the left side, not an object. So the correct method would be (&(A::voidfunction)).

Semantics. He uses classA as a single identifier for the class name; you use A.

quote:1: Just because a function is in a class rather than outside of one, does it really chage it? I mean, ovbiously it does in my case, but isn''t there a way to just have a typedef for both functions in and outside of classes? And what if I have two classes that have a void function and I want to assign one or the other depending on some condition? Do I then have to have a typedef for the function in both class A and class B?

In order, yes, no, yes.

Yes, having a function in a class changes its defintion to only be valid relative to that class. No, you can''t just have a function pointer for all types of classes (unless they all inherit from a base class, but in such a case virtual functions are a better solution). yes, you have to have separate typedefs for class A and class B.

quote:When you set the function in class B equal to A::functionA, well, how would the compiler know which x to add? classA1.x, classA2.x, or classA3.x?

Whichever object it is called relative to. Try it and be amazed.


I wanna work for Microsoft!
Dactylos:
I see. Your code seems to work, but I have a question:

Since I am putting the function in the classB, how would I call it? Would I have to go like this:
classA.(classB.functionPointer)(); ?

That seems kinda pointless. I mean, if I wanted to call the function from class A, I could just do it directly from A, instead of a big circle like that.

I could also include a classA inside classB so it'd be like:

classB.classA.(functionPointer)(); but again, that seems like too much to be doing. Are these the only two ways I could do it?

--Vic--

Edited by - Roof Top Pew Wee on November 9, 2001 6:53:21 PM

This topic is closed to new replies.

Advertisement