Function Pointers
Another interesting piece of functionality that C++ pointer arithmetic provides is direct addressing of functions. Like variables, functions have memory addresses. To illustrate, let's say that you create a function called myFunction:
void myFunction(int x) { printf( "%d\n", x ); }
You can assign a pointer to the function address as follows:
void (*fptr)(int); fptr = &myFunction;
The ampersand (&) signifies the address of the function. You can call the function in the usual way or by using the pointer. Finally, you can output the actual address of the function by using the following code:
// print the actual address of the function printf( "The pointer address is %d\n", *fptr );
Listing 6 demonstrates these functionalities of function pointers.
Listing 6A function pointer example.
// Pointer03.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <iostream> void myFunction(int x) { printf( "%d\n", x ); } int main() { void (*fptr)(int); fptr = &myFunction; // call myFunction the old fashioned way myFunction(11); // use the function pointer (*fptr)(22); // print the actual address of the function printf( "The pointer address is %d\n", *fptr ); system ("pause"); return 0; }
The output from this code is shown in Figure 8. Make special note of the address of the function itself.
Figure 8 Inspecting the address of a function.
Why would you want to use a function pointer? Occasionally you might not know ahead of time which functions need to be called; you can handle this situation by accepting a pointer to a function instead of calling the function itself. Let's look at a possible scenario from Alex Allain's article "Programs as Data: Function Pointers":
If you were to write a sort routine, you might want to allow the function's caller to choose the order in which the data is sorted; some programmers might need to sort the data in ascending order, others might prefer descending order, while still others may want something similar to but not quite like one of those choices. One way to let your user specify what to do is to provide a flag as an argument to the function, but this is inflexible; the sort function allows only a fixed set of comparison types (e.g., ascending and descending).
A much nicer way of allowing the user to choose how to sort the data is simply to let the user pass in a function to the sort function. This function might take two pieces of data and perform a comparison on them.
One implementation of function pointers that a colleague and I developed many years ago pertained to constructing a generic search routine. In this situation, the function was passed data and had no idea what the data type was until it received the actual data. Since each data type required the use of a different search routine, we used a collection of function pointers to call the appropriate function at runtime.