|
-
March 4th, 2010, 04:12 PM
#1
Function Pointers
First of all, thank you in advance for your time.
Can I use a function pointer but when that function belongs to an object in a given class?
For example:
Code:
//// Example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
class Example {
public:
int funcA(int, int);
static int staticFuncB(int a, int b);
};
#endif
Code:
//// Example.cpp
#include "Example.h"
int Example::funcA(int a, int b) {
return a * b;
}
int Example::staticFuncB(int a, int b) {
return a * b;
}
Code:
//// Main.cpp
#include <stdio.h>
#include "Example.h"
int ejecutaFunc(int a, int b, int (*func)(int, int)) {
return (*func)(a, b);
}
int main() {
Example * a = new Example();
int resp1 = a->funcA(2, 3);
int resp2 = ejecutaFunc(2, 3, Example::staticFuncB); // Works
//int resp2 = ejecutaFunc(2, 3, a->funcA); // Failure
delete a;
return 0;
}
Is there any way to generate this behavior?
Code:
int resp2 = ejecutaFunc(2, 3, a->funcA);
Thank you
Last edited by xlarsx; March 5th, 2010 at 09:29 AM.
-
March 4th, 2010, 04:30 PM
#2
Re: Function Pointers
Yes you can. A member function pointer is declared as
Code:
typedef void ('class'::*PTR)(void);
assigned as
Code:
PTR p = &'class instance'::'memberfunction';
and called as
Code:
('class instance'.*p)();
-
March 4th, 2010, 04:32 PM
#3
Re: Function Pointers
Yes, but it's a bit complicated.
The problem is that non-static member methods have a hidden "this" parameter which changes their signature. Therefore, they won't work with the obvious function pointer.
There are two basic approaches to solve the problem.
1) If you're really forced to work with function pointers, then define a static function (or a free function) which takes all the normal arguments, plus a pointer to the object, and then just invokes the method. This static or free function can be assigned to a function pointer no problem.
2) If you're not working with a C-based 3rd-party library requiring C-compatible function pointers, you have more options. Rather than use a function pointer you can use a functor, which is constructed with the object to be operated on and invokes the desired method in its operator(). This will work great if you're passing the functor to a template-defined parameter of a function; but in some cases (say, storing lots of function pointers and functors etc in a container), just letting templates handle things won't work since the underlying types are different. In that case, something like boost::function steps in to solve the problem------all functors and function pointers with a common signature are implicitly convertible to to a single boost::function type.
Speaking of Boost, the easiest way to construct an appropriate functor for a given member method is to just use boost::bind rather than writing the functor yourself.
-
March 4th, 2010, 05:00 PM
#4
Re: Function Pointers
Perfect, applied to the example given it is:
Code:
int ejecutaFunc(int a, int b, Example ref, int (Example:: * func)(int, int)) {
return (ref.*func)(a, b);
}
int main() {
Example a = Example();
int resp1 = a.funcA(2, 3);
int resp2 = ejecutaFunc(2, 3, a, &Example::funcA);
return 0;
}
Thank you very much
Last edited by xlarsx; March 5th, 2010 at 09:28 AM.
-
March 4th, 2010, 05:40 PM
#5
Re: Function Pointers
 Originally Posted by Lindley
1) If you're really forced to work with function pointers, then define a static function (or a free function) which takes all the normal arguments, plus a pointer to the object, and then just invokes the method. This static or free function can be assigned to a function pointer no problem.
Thank you very much for the advice, as to point 1, I tried to apply it to getting this code:
Code:
//// Main.cpp
#include <stdio.h>
#include "Example.h"
int ejecutaFunc(int a, int b, int (*func)(int, int)) {
return (*func)(a, b);
}
int main() {
Example a = Example();
int resp1 = a.funcA(2, 3);
int resp2 = ejecutaFunc(2, 3, &Example::staticFuncB);
if (resp1 != resp2)
printf("Error");
return 0;
}
Code:
//// Example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
class Example {
private:
static Example * objRef;
public:
int funcA(int, int);
static int staticFuncB(int a, int b);
};
#endif
Code:
//// Example.cpp
#include "Example.h"
int Example::funcA(int a, int b) {
return a * b;
}
int Example::staticFuncB(int a, int b) {
Example e = (*objRef);
typedef int (Example:: * func)(int, int);
func f = &Example::funcA;
return (e.*f)(a, b);
}
And it just works... but I think that because in Example.cpp:
Code:
Example e = (*objRef);
it points to 0, it must fail... but it doesn't, why?
And about the second point I just can't visualize it, would you have some reference that you can recommend me?
Thank you
Last edited by xlarsx; March 5th, 2010 at 09:30 AM.
-
March 4th, 2010, 07:06 PM
#6
Re: Function Pointers
 Originally Posted by xlarsx
And it just works... but I think that because in Example.cpp:
Example e = (*objRef);
it points to 0, it must fail... but it doesn't, why?
There is no such thing as "must fail" in C++ for things where exceptions are not guaranteed to be thrown. The only thing guaranteed with that line of code is that the behaviour is undefined.
Secondly, please use code tags when posting code. The code you're posting is unformatted and almost unreadable without code tags.
Example:
Compare this:
class Example {
private:
static Example * objRef;
public:
int funcA(int, int);
static int staticFuncB(int a, int b);
};
to this:
Code:
class Example {
private:
static Example * objRef;
public:
int funcA(int, int);
static int staticFuncB(int a, int b);
};
Regards,
Paul McKenzie
-
March 5th, 2010, 03:49 PM
#7
Re: Function Pointers
@Paul Mckenzie
Thanks for the advice of the code block, I had not noticed that feature.
Furthermore, the system is running properly while not in use references the object in question is null.
Thanks
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|