Function Pointers?

Started by
14 comments, last by pragma Fury 18 years, 10 months ago
I dont understand function pointers, what are they used for?? Can anyone show how you would use one? They basically call another function??I dont see any practical use for that.
Advertisement
C++ virtual functions are basically implemented by injecting a pointer to a table of function pointers in every object of a class that has virtual functions. At run-time, the system relies on these pointers to figure out which version of the function it is supposed to call.

If you were building a text-based RPG, you would want to associate each command the user can type with a function. The easiest way to do that is to have a table of string/function pointer pairs.

You can store a function pointer with the data associated with a button in a GUI to determine the function that gets called when the button is pressed. You can dynamically change that association by assigning a different function pointer to the button.

More generally you can cause a function to be called when an event occurs, and change the event/function pairings at your whim.
"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
You cant do that by just calling the function?
Quote:Original post by Gink
You cant do that by just calling the function?


But if you "just call the function", you have to tell the computer, right there in your code, which function you want to call. Using function pointers, this information can be treated as data. You can store it, change it ... until you actually use it and call the function.

The code that uses the function pointer doesn't need to know precisely which function it is calling. In Win32 programming, you often provide the system which callback functions: pointer to functions you want the system to call in such and such circumstances. The Win32 framework doesn't actually know what functions you're going to provide it with; it only knows their signatures (parameters and return type), so that it can actually call them, but that's it.
"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
Use #1: Callbacks.

Suppose I design a container class that implements some type of sorting functionality. But, I want the user of my class to be able to specify how items in my container are to be sorted by specifying their own comparison function.
The STL containers use this all over the place. Another example would be the qsort function.

There are a number of other uses for callbacks, like event notifications and such, but you get the idea.


Use #2: Run-time logic

This probably isn't a good example, but it's the first one that popped into my head. You could create a mapping between a command and an action.
Something like this: (note that I just winged this.. I havn't used function pointers for a while, so the syntax may not be 100% correct.. here's a good reference though)
typedef void (*ActionFunction)();std::map<std::string, ActionFunction> mapActions;// add actions to our mapmapActions["hit"] = myHitFunction;mapActions["give"] = myGiveFunction;mapActions["run"] = myRunFunction;/* ... elsewhere*/// call the "hit" method.mapActions["hit"]();


Yes, you could do this with a bunch of chained "if-else if" statements, but this method is cleaner, and potentially faster if you have a LOT of possible actions.


Edit: Possible Use #3:
Just had this thought.. you could create an array/vector/dequeue/whatever of function pointers to implement a rudimentary call stack.
Basic example, as I've not seen it directly covered in this post (although pragma Fury covers more complex examples and stuff :-))

#include <iostream>using namespace std;void foo ( void ) {    cout << "foo" << endl;}void bar ( void ) {    cout << "bar" << endl;}int main ( void ) {    void (*foo_or_bar)( void );    foo_or_bar = foo;    foo_or_bar(); //prints "foo"    foo_or_bar = bar;    foo_or_bar(); //prints "bar"}

Pragma Fury, I don't know what you were planning to do with your second implementation, but I do know that that mapping of strings to functions is the basis of my console at least, and if I didn't have function pointers, I'd be stuck with a lot of repetative, ugly code.
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
So they are used for convenience and not because they are needed?

that looks alot like javas polymorphism technique now that i see it =p
Quote:Original post by Gink
So they are used for convenience and not because they are needed?


In many cases they are needed. Without them, the C library function qsort, mentioned by pragma Fury would be impossible. Since the function lives in a library, you cannot modify it to call whichever comparison operations is correct for your code (you don't compare ints and strings the same way). So there would have to be one such function for each type of entity to compare. And if you were to come up with your own type, an array of which you want to sort, you would be out of luck and would have to rewrite the sorting function yourself.

A function pointer allows you to tell qsort which comparison function is to be used. The qsort function itself doesn't know anything about how your comparison works (in fact, it knows precious little about what you're passing it), and just uses it as a black box in its quicksort algorithm.

With a function pointer, you can call "the function stored in the pointer" without explicitely specifying (at the call point) which function is to be called. That information becomes data, not code.
"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
Quote:Original post by SirLuthor
Pragma Fury, I don't know what you were planning to do with your second implementation, but I do know that that mapping of strings to functions is the basis of my console at least, and if I didn't have function pointers, I'd be stuck with a lot of repetative, ugly code.


Actually, the only place I've used string->function mapping was in a quasi-sql driver I did for work. Long story short, we used it to make our own stored proc style function calls. I just adapted it to a more game-like scenerio.

Quote:Original post by Gink
So they are used for convenience and not because they are needed?


I would somewhat agree with this. A lot of what you can do with function pointers can be done in an alternate way. Though that often results in some very nasty code and bad design practices.

This topic is closed to new replies.

Advertisement