www.Function Pointer.org
The site dedicated to C and C++ Function Pointers


Exit  Download  Links  Contact  Disclaimer  Main  Deutsch

The Function Pointer Tutorials

 Extensive Index
 1.  Introduction to Function Pointers
 2.  The Syntax of C and C++ Function Pointers
 3.  How to Implement Callbacks in C and C++ ?
 4.  Functors to encapsulate C and C++ Function Pointers
 5.  Topic Specific Links

1.  Introduction to Function Pointers Main Index top
   1.1  What is a Function Pointer ?
   1.2  Introductory Example or How to Replace a Switch-Statement

Function Pointers provide some extremely interesting, efficient and elegant programming techniques. You can use them to replace switch/if-statements, to realize your own late-binding or to implement callbacks. Unfortunately - probably due to their complicated syntax - they are treated quite stepmotherly in most computer books and documentations. If at all, they are addressed quite briefly and superficially. They are less error prone than normal pointers cause you will never allocate or deallocate memory with them. All you've got to do is to understand what they are and to learn their syntax. But keep in mind: Always ask yourself if you really need a function pointer. It's nice to realize one's own late-binding but to use the existing structures of C++ may make your code more readable and clear. One aspect in the case of late-binding is runtime: If you call a virtual function, your program has got to determine which one has got to be called. It does this using a V-Table containing all the possible functions. This costs some time each call and maybe you can save some time using function pointers instead of virtual functions. Maybe not ... BTW: Modern compilers are very good! With my Borland Compiler the time I was able to save calling a virtual function which multiplies two floats was about 2 percent.


1.1  What is a Function Pointer? Main Index top

Function Pointers are pointers, i.e. variables, which point to the address of a function. You must keep in mind, that a running program gets a certain space in the main-memory. Both, the executable compiled program code and the used variables, are put inside this memory. Thus a function in the program code is, like e.g. a character field, nothing else than an address. It is only important how you, or better your compiler/processor, interpret the memory a pointer points to.


1.2  Introductory Example or How to Replace a Switch-Statement Main Index top

When you want to call a function DoIt() at a certain point called label in your program, you just put the call of the function DoIt() at the point label in your source code. Then you compile your code and every time your program comes up to the point label, your function is called. Everything is ok. But what can you do, if you don't know at build-time which function has got to be called? What do you do, when you want to decide it at runtime? Maybe you want to use a so called Callback-Function or you want to select one function out of a pool of possible functions. However you can also solve the latter problem using a switch-statement, where you call the functions just like you want it, in the different branches. But there's still another way: Use a function pointer!

In the following example we regard the task to perform one of the four basic arithmetic operations. The task is first solved using a switch-statement. Then it is shown, how the same can be done using a function pointer. It's only an example and the task is so easy that I suppose nobody will ever use a function pointer for it ;-)


   //-----------------------------------------------------------------------------------------
   // 1.2 Introductory Example or How to Replace a Switch-Statement
   // Task: Perform one of the four basic arithmetic operations specified by the
   //       characters '+', '-', '*' or '/'.


   // the four arithmetic operations
   // one of these functions is selected at runtime with a swicth or a function pointer
   float Plus     (float a, float b) { return a+b; }
   float Minus    (float a, float b) { return a-b; }
   float Multiply (float a, float b) { return a*b; }
   float Divide   (float a, float b) { return a/b; }


   // solution with a switch-statement - <opCode> specifies which operation to execute
   void Switch(float a, float b, char opCode)
   {
      float result;

      // execute operation
      switch(opCode)
      {
         case '+' : result = Plus      (a, b); break;
         case '-' : result = Minus     (a, b); break;
         case '*' : result = Multiply  (a, b); break;
         case '/' : result = Divide    (a, b); break;
      }

      cout << "switch: 2+5=" << result << endl;          // display result
   }


   // solution with a function pointer - <pt2Func> is a function pointer and points to
   // a function which takes two floats and returns a float. Thefunction pointer
   // "specifies" which operation shall be executed.
   void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
   {
      float result = pt2Func(a, b);                         // call using function pointer

      cout << "switch replaced by function pointer: 2-5=";  // display result
      cout << result << endl;
   }


   // execute example code
   void Replace_A_Switch()
   {
      cout << endl << "Executing function 'Replace_A_Switch'" << endl;

      Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
      Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
   }

Important note: A function pointer always points to a function with a specific signature! Thus all functions, you want to use with the same function pointer, must have the same parameters and return-type!

2.  The Syntax of C and C++ Function Pointers Main Index top
   2.1  Define a Function Pointer
   2.2  Calling Convention
   2.3  Assign an Address to a Function Pointer
   2.4  Comparing Function Pointers
   2.5  Calling a Function using a Function Pointer
   2.6  How to Pass a Function Pointer as an Argument ?  new
   2.7  How to Return a Function Pointer ?  new
   2.8  How to Use Arrays of Function Pointers ?

Regarding their syntax, there are two different types of function pointers: On the one hand there are pointers to ordinary C functions or static C++ member functions, on the other hand there are pointers to non-static C++ member functions. The basic difference is that all pointers to non-static member functions need a hidden argument: The this-pointer to an instance of the class. Always keep in mind: These two types of function pointers are incompatible with each other.

2.1  Define a Function Pointer
Since a function pointer is nothing else than a variable, it must be defined as usual. In the following example we define two function pointers named pt2Function and pt2Member. They point to functions, which take one float and two char and return an int. In the C++ example it is assumed, that the function, our pointer points to, is a member function of TMyClass.


   // 2.1 define a function pointer
   int (*pt2Function)        (float, char, char);           // C
   int (TMyClass::*pt2Member)(float, char, char);           // C++

2.2  Calling Convention
Normally you don't have to think about a function's calling convention: The compiler assumes __cdecl as default if you don't specify another convention. However if you want to know more, keep on reading ... The calling convention tells the compiler things like how to pass the arguments or how to generate the name of a function. Examples for other calling conventions are __stdcall, __pascal and __fastcall. The calling convention belongs to a functions signature: Thus functions and function pointers with different calling convention are incompatible with each other!. You specify a specific calling convention between the return type and the function's or function pointer's name. Note: This is correct for my Borland compiler. I found different explanations on the web and thus I don't know, what's really correct. If someone knows: Let me know;-)

2.3  Assign an address to a Function Pointer
It's quite easy to assign the address of a function to a function pointer. You simply take the name of a suitable and known function or member function. It's optional to use the address operator & infront of the function's name. Note: You may have got to use the complete name of the member function including class-name and scope-operator (::). Also you have got to ensure, that you are allowed to access the function right in scope where your assignment stands.


   // 2.3 assign an address to the function pointer

   // C
   int DoIt  (float a, char b, char c){ cout << "DoIt"   << endl; return a+b+c; }
   int DoMore(float a, char b, char c){ cout << "DoMore" << endl; return a-b+c; }

   pt2Function = DoMore;               // assignment
   pt2Function = &DoIt;                // alternative using address operator


   // C++
   class TMyClass
   {
   public:
       int DoIt  (float a, char b, char c){ cout << "TMyClass::DoIt"   << endl; return a+b+c; };
       int DoMore(float a, char b, char c){ cout << "TMyClass::DoMore" << endl; return a-b+c; };

      /* more of TMyClass */
   };
   pt2Member = TMyClass::DoIt;         // assignment
   pt2Member = &TMyClass::DoMore;      // alternative using address operator

2.4  Comparing Function Pointers
You can use the comparison-operator (==) the same way. In the following example it is checked, whether pt2Function and pt2Member actually contain the address of the functions DoIt and TMyClass::DoMore. A text is shown in case of equality.


   // 2.4 comparing function pointers

   // C
   if(pt2Function == &DoIt)
      cout << "pointer points to DoIt" << endl;

   // C++
   if(pt2Member == &TMyClass::DoMore)
       cout << "pointer points to TMyClass::DoMore" << endl;

2.5  Calling a Function using a Function Pointer
In C you have two alternatives of how to call a function using a function pointer: You can just use the name of the function pointer instead of the name of the function or you can explicitly dereference it. In C++ it's a little bit tricky since you need to have an instance of a class to call one of their (non-static) member functions. If the call takes place within another member function you can use the this-pointer.


   // 2.5 calling a function using a function pointer
   int result1 = pt2Function    (12, 'a', 'b');          // C short way
   int result2 = (*pt2Function) (12, 'a', 'b');          // C

   TMyClass instance;
   int result3 = (instance.*pt2Member)(12, 'a', 'b');    // C++
   int result4 = (*this.*pt2Member)(12, 'a', 'b');       // C++ if this-pointer can be used

2.6  How to Pass a Function Pointer as an Argument ?
You can pass a function pointer as a function's calling argument. You need this for example if you want to pass a pointer to a callback function. The following code shows how to pass a pointer to a function which returns an int and takes a float and two char:


   //-----------------------------------------------------------------------------------------
   // 2.6 How to Pass a Function Pointer

   // <pt2Func> is a pointer to a function which returns an int and takes a float and two char
   void PassPtr(int (*pt2Func)(float, char, char))
   {
      float result = pt2Func(12, 'a', 'b');     // call using function pointer

      cout << result << endl;
   }

   // execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
   void Pass_A_Function_Pointer()
   {
      cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
      PassPtr(&DoIt);
   }

2.7  How to Return a Function Pointer ?
It's a little bit tricky but a function pointer can be a function's return value. In the following example there are two solutions of how to return a pointer to a function which is taking a float and returns two float. If you want to return a pointer to a member function you have just got to change the definitions/declarations of all function pointers.


   //-----------------------------------------------------------------------------------------
   // 2.7 How to Return aFunction Pointer
   //     'Plus' and 'Minus' are defined above in 2.1-4. They return a float and take two float


   // direct solution
   // function takes a char and returns a pointer to a function which is taking two
   // floats and returns a float. <opCode> specifies which function to return
   float (*GetPtr1(const char opCode))(float, float)
   {
      if(opCode == '+')  return &Plus;
      if(opCode == '-')  return &Minus;
   }


   // solution using a typedef
   // define a pointer to a function which is taking two floats and returns a float
   typedef float(*pt2Func)(float, float);

   // function takes a char and returns a function pointer which is defined as a
   // type above. <opCode> specifies which function to return
   pt2Func GetPtr2(const char opCode)
   {
      if(opCode == '+')  return &Plus;
      if(opCode == '-')  return &Minus;
   }


   // execute example code
   void Return_A_Function_Pointer()
   {
      cout << endl << "Executing 'Return_A_Function_Pointer'" << endl;

      float (*pt2Function)(float, float);     // define a function pointer

      pt2Function=GetPtr1('+');               // get function pointer from function 'GetPtr1'
      cout << pt2Function(2, 4) << endl;      // call function using the pointer


      pt2Function=GetPtr2('-');               // get function pointer from function 'GetPtr2'
      cout << pt2Function(2, 4) << endl;      // call function using the pointer
   }

2.8  How to Use Arrays of Function Pointers ?
Operating with arrays of function pointers is very interesting. This offers the possibility to select a function using an index. The syntax appears difficult, which frequently leads to confusion.


  //-----------------------------------------------------------------------------------------
   // 2.8 How to Use Arrays of Function Pointers

   // C
   // type-definition: 'pt2Function' now can be used as type
   typedef int (*pt2Function)(float, char, char);

   // illustrate how to work with an array of function pointers
   void Array_Of_Function_Pointers()
   {
      cout << endl << "Executing 'Array_Of_Function_Pointers'" << endl;

      // <funcArr> is an array with 10 pointers to functions which return an int
      // and take a float and two char
      pt2Function funcArr[10];

      // assign the function's address - 'DoIt' and 'DoMore' are suitable functions
      // like defined above in 2.1-4
      funcArr[0] = &DoIt;
      funcArr[1] = &DoMore;
      /* more assignments */

      // calling a function using an index to address the function pointer
      cout << funcArr[1](12, 'a', 'b') << endl;
      cout << funcArr[0](12, 'a', 'b') << endl;
   }


   // C++
   // type-definition: 'pt2Member' now can be used as type
   typedef int (TMyClass::*pt2Member)(float, char, char);

   // illustrate how to work with an array of member function pointers
   void Array_Of_Member_Function_Pointers()
   {
      cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;

      // <funcArr> is an array with 10 pointers to member functions which return an
      // int and take a float and two char
      pt2Member funcArr[10];

      // assign the function's address - 'DoIt' and 'DoMore' are suitable member functions
      // of class TMyClass like defined above in 2.1-4
      funcArr[0] = &TMyClass::DoIt;
      funcArr[1] = &TMyClass::DoMore;
      /* more assignments */

      // calling a function using an index to address the member function pointer
      // note: an instance of TMyClass is needed to call the member functions
      TMyClass instance;
      cout << (instance.*funcArr[1])(12, 'a', 'b') << endl;
      cout << (instance.*funcArr[0])(12, 'a', 'b') << endl;
   }

3.  How to Implement Callbacks in C and C++ ? Main Index top
4.  Functors to encapsulate C and C++ Function Pointers
5.  Topic Specific Links


Download zipped Postscript Download PDF Download zipped HTML-Files You can download a zipped Postscript, a PDF or zipped HTML-Files of the tutorials about Function Pointers, Callbacks and Functors!
Download Example Source You can also download the zipped source-files with all examples of the tutorials!


new Newsgroup about function pointers! new


last updated: 10.07.01
© 2000/2001 by lars haendel
All code pieces were highlighted using the free lore's source converter. All trademarks are the sole property of their respective owners. I do NOT promote, speak in the behalf of, advertise or work for ANY computing, news or internet profit business. Everything I do, I do it for fun! If you have questions, annotations, contributions, want to suggest a link or found a bug: Mail me!!!! 

BTW something about bugs: Yes, there are bugs on these pages and they will stay and enjoy their being as long as I find them or you tell me about them. Almost nobody writes a bug report if he encounters an error. But it's so easy for you: Just drop me a few lines in a mail. It won't take you more than 3 minutes. I spend much time to make these pages and I did it for YOU!