Function Pointer Basics in C++

Function Pointers (Fencers)Beginners to C++ programming find the concept of pointers foreign to them. Pointers, and code that manipulates pointers (aka pointer arithmetic), can even be daunting to some of the most seasoned programmers. Pointers in C++ account for a fair share of bugs in programs due to the lack of understanding. So why even use them? Well, besides being the most problematic, they are also some of the most powerful features in the language. Pointers make it quick to point to large objects in memory while they themselves are small. You could have a large stack of objects in memory and change a pointer to point to each one individually without wasting time copying the large objects around in memory.

Function names are their own type of pointer

This article is going to assume you have the concept of a variable pointer already down. What you may not know is that when you call a function using its name, you too are using another kind of pointer. These types of pointers point to locations of functions. Again, a memory location but instead of a variable value, we are pointing to a function out there in memory. Let’s talk about a function call…

printHello();

In the code above we are calling a function named “printHello”. The actual word “printHello” is a pointer to a function. When we make the call, we use this “printHello” pointer to find the function in memory, execute it and giving it any parameters we put in between the parenthesis (in this case none). Where variable pointers hold memory addresses of other variables, here this pointer holds the address of a function to execute.

C++ lets you create these pointers and then assign functions to them. Once you make the connection between the pointer and the function, you can call that function using the pointer. Now you may be asking “What in the hell is that good for?” The answer is “A few things like assigning user defined functions or passing around functions like a variable.” The second question you may be asking is “Is this a common thing to do?” and the answer is “Not really common… consider it a fringe or niche concept.”

Let’s take a look at a few examples of what we might be able to do with this concept and how to set it up…

#include <iostream>
#include <string>
using namespace std;

void printAttack();
void printDefend();

int main() {

	// Function pointer called "printStatement"
	// It can point to functions which return void and takes no parameters
	void (*printStatement)();


	// Assign each function to this pointer, use pointer to call them.
	printStatement = printAttack;
	printStatement();

	printStatement = printDefend;
	printStatement();

	// Above is implicit version (some older compiler may not support it)
	// Below again call but with explicit version
	// Dereference pointer and then use it to call printDefend again
	(*printStatement)();

	return 0;
}

// Notice these two functions return nothing and take no parameters
// Which matches our function pointer signature.
void printAttack() {
	cout << "Ah Ha! En garde!" << endl;
}

void printDefend() {
	cout << "I thwart your attack dear sir!" << endl;
}

This contrived example above is made ridiculously simple just to show how this works. In addition to main(), I have defined two standard printing statements. One for printing an attack statement and another to print a defend statement. Sword fighting game perhaps? ;)

In main you will see I created a function pointer variable called “printStatement”. It is a function pointer saying that it can point to any function which has a matching signature. In this case the functions it can point to are those which have a return type of void and takes no parameters. Notice our two print functions, printAttack and printDefend, which both have a return type of void and take no parameters… they match the pointer. The syntax for our pointer is a bit funky because we use parentheses around *printStatement. This is because if we don’t, it will be evaluated as void *printStatement(), a function call that takes no parameters and returns a pointer.

In our example we assign each of the functions to this pointer and then use the pointer to call the associated function. Notice I can call both printAttack and printDefend through the same pointer. I just changed which function the pointer was pointing to. As a side note, there are two ways to call the associated function, implicitly and explicitly. I demonstrate both here. Can you create a third statement and give it to the same pointer then call it? Try it!

Passing function pointers to other functions

This example is nice, but you might be asking yourself “can I pass these pointers around to functions?” You sure can! This is where it really shines because you could essentially write a function that accepts a function pointer and have it call that function without ever knowing what it is really calling. This would give you a generic utility function that you can give you the ability to call a multitude of different functions. Perhaps functions that haven’t even been written into the program yet. Extensibility for the win!

Here is an example…

#include <iostream>
#include <string>
using namespace std;

void printMoves(void (*printStatement)(string));
void printSomeText(string);

int main() {

	// Function pointer called "printStatement"
	// It can point to functions which return void and takes a string parameter
	void (*printStatement)(string moveText);


	// Set the pointer to point to our function for printing
	// Notice that printSomeText matches the pointer signature
	printStatement = printSomeText;

	// Pass the pointer to our printMoves function
	printMoves(printStatement);


	return 0;
}

// Use the passed pointer to a function to call printSomeText 
// with different strings
void printMoves(void (*printStatement)(string move)) {
	printStatement("Ah ha! En garde!");
	printStatement("I thwart your attack dear sir!");
}


// Very generic function, could be one of many that our pointer could 
// possibly point to.
void printSomeText(string theMove) {
	cout << theMove << endl;
}

We are introducing a few new things here. Again I have two functions. One of them is very generic taking in a string and printing it. The other one, printMoves, takes a parameter which is a function pointer. This function pointer can point to functions which return void and take one string parameter. So again in main() we create a function pointer and we assign it the function printSomeText (notice how the signature of printSomeText matches the function pointer). Then we pass that pointer to printMoves which uses the pointer and gives it a few statements to print… our attack and defend statements from earlier. But you know what? printMoves has no idea that it is calling printSomeText. It is just going to the memory location pointed to by printStatement and give it the text.

We could have just as easily created another function called “printMoreText” set the pointer to point to that instead and give it to printMoves and it would have called that function all the same. One situation we could give it printSomeText and in another give it printMoreText all without having to change printMoves.

If you are familiar with .NET, this concept is similar to delegates. They are essentially function pointers as well but with a little more flexibility. Here in C++ we could have the user create their own functions and give them to printMoves to invoke, we could have 10 different print functions that all have the same signature but do different things, printMoves would handle them all. Generic here is good and this sort of thing can be found in a ton of utility programs.

Using TypeDef to Simplify

One last thing I want to mention about function pointers is the idea of simplifying the pointers down using typedef. Using typedef we could have cleaned up a little bit of the syntax with a statement like…

typedef void (*printStatement)(string);

Then anywhere we wanted to have a function pointer to point to functions that return void and takes a string parameter we would simply use “printStatement”….

void printMoves(printStatement func) {
	func("Ah ha! En garde!");
	func("I thwart your attack dear sir!");
}

I think if you play with the two programs I provided above you will realize their flexibility and how you might use them. You may not use this concept every day, but at least you can impress your friends at dinner parties! That right there is worth its weight in free pizza. Thanks for reading! :)

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebook "The Programmers Idea Book". He has been a programmer for over 17 years. He works for a hot application development company in Vancouver Canada which service some of the biggest telecoms in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.
  • bj

    Should probably note this does not work with c++ class methods..

    • http://www.coderslexicon.com Martyr2

      Actually you can, you can create pointers to non-static member functions. Below is an example…

      class OurClass
      {
         public:
            void DoSomething(){ cout << "Did Something"<< endl; };
      };
      
      // Now lets point to it and then use an instance of the class to get at it.
      
      int main() {
      	void (OurClass::*pt2Member)() = NULL;          
      
      	pt2Member = &OurClass::DoSomething;
      
      	OurClass *ourClassExample = new OurClass();
      
      	(ourClassExample->*pt2Member)();
      
      	return 0;
      }
      

      Notice how we use an instance of our class, then resolve its pointer to then get at the DoSomething() method of the class.

      Hope that increases understanding… even though it is a little beyond the scope of this particular article. Thanks for the feedback! :)

  • http://www.itoctopus.com Fadi El-Eter

    The last time I used pointers was back in the university. I remember that a small bug immediately led to a blue screen (used to work on Borland C++).

    We have to be thankful everyday for the abundance of programming languages nowadays that do not require one to work with pointers!

    Thanks for sharing!