Jump to content

  • Log In with Google      Sign In   
  • Create Account


Like
0Likes
Dislike

Using Function Pointers

By Jason Mickela | Published Jul 01 2004 07:15 AM in Game Programming

function pointers class code int pointer void execute call
If you find this article contains errors or problems rendering it unreadable (missing images or files, mangled code, improper text formatting, etc) please contact the editor so corrections can be made. Thank you for helping us improve this resource



This article describes how to use function pointers in various ways to increase the performance and/or the readability of your code. I will try to make this as easy to understand as possible for
people just learning C or C++ or people that have not learned about function pointers yet.


Functions pointers can be a little intimidating for people just learning programming. I remember when I was first learning C, just the concept of pointers was vague enough for me without having to
worry about what the heck a pointer to a function was. For this reason I think most people skipped learning about them in order to preserve their sanity. However they are actually very useful.


What are function pointers?

Function pointers are variables that point to a function, and can be used to call that function. On the surface this may not seem that useful but I will describe a few things I have used them
for.


How to use them

Using function pointers is relatively simple easy, assuming you are familiar with pointers. The following code defines a pointer to the function that is declared.



int set_number(int a, int *b);



//The type in front matches the function return type, and the types in back 

//match the argument list.

int (*funcpointer)(int, int *);



//Assign the function to the pointer.

funcpointer = set_number;



//Now call the function

int a = (*funcpointer)(5, &someint);


There, that isn't so hard now is it? There are a few different ways you can do this, so if you see someone doing this a slightly different way don't worry. I use this way because it is most like
the syntax necessary to use function pointers within a C++ class, which I will describe next.


How to use function pointers within a class

Using function pointers within a class can greatly improve the usefulness and adaptability of a class. However it is a bit harder to get them working, especially if you are used to the shorthand
version of the code that I used in the previous section.


The following code defines a small class that includes a function and a pointer to that function.



class CTurret

{

 public:

   //This creates a function pointer named Draw

   void (CTurret::*Draw)(float);

   

   //The setup code in this class selects which version to draw, these

   //functions never get called directly in code.

   void  DrawHiRes(float fAngle);

   void  DrawLowRes(float fAngle);



   void setup()

   {

      //Depending on a setting in the code you can change where the

      //Draw variable points and easily change how the program flows

      //without going through the if statements every frame.

      if(HIGH_RES)

         Draw = DrawHiRes;

      else

         Draw = DrawLowRes;

   }

};



...

//Calling the function

(turret.*Draw)(angle);

...


In this code an object (class) is created to manage a turret object. In a real game this class would hold data like position, hitpoints, and other various data that the game would need. In this
sample I’ve only included things related to function pointers.


The line:



void (CTurret::*Draw)(float);


creates a pointer to a CTurret member function that will be named Draw. The function it points to will take a single float as an argument.


The lines:



void  DrawHiRes(float fAngle);

void  DrawLowRes(float fAngle);


create two functions to render this object in either high or low resolution mode. If your game supported multiple detail modes you would normally have to use an if statement every frame to decide
which of these functions to use when drawing.


In the setup function the HIGH_RES variable is used to determine where Draw should point. HIGH_RES could be a global variable or something passed to the constructor or init function when this
object was created. You can see that assigning a value to a function pointer is as easy as a normal pointer. Just pretend that the name of the function you want to point to is a variable name.


And lastly you can see the syntax for calling the function using the function pointer. This is a simplified example but it does show all the steps you need to implement function pointers in any
C++ object.


How to use them for flow control in a state machine

Now it's time to put the Fun in Function Pointer. For the longest time I didn't even think about functions pointers until I was looking at a state machine one day and wished that instead of having
a switchboard of if statements that executed single functions based on the state of the program, the class would just automatically execute the function appropriate for the current state. I
realized that I could accomplish this with function pointers. I will create a small example class with various member function and a state changing function that will switch the current execute
function. This is a good example of how to use function pointers to control the flow of a program and eliminating the if statements that you hit every time you call that function (which can be
once per frame or more).



#define STATE_START 1

#define STATE_TITLE 2

#define STATE_MMENU 3

#define STATE_RUNGM 4



class CExample

{

   int nState;

   

 public: 



   int Startup();

   int TitleScreen();

   int MainMenu();

   int RunGame(); 



   int (CExample::*Execute)();



   void SetState(int nNewState)

   {

      nState = nNewState;

      if(nState == STATE_START)

         Execute = Startup;

         

      else if(nState == STATE_TITLE)

         Execute = TitleScreen;

        

      else if(nState == STATE_MMENU)

         Execute = MainMenu;



      else if(nState == STATE_RUNGM)

         Execute = RunGame;

   }

};


In this function all you have to do is call Execute() and it will call the function appropriate for the current state. This is a huge advantage because you have to call Execute every frame and
this is eliminating the overhead of querying the game state. It may not seem like much, but sometimes every instruction counts.


Using Function Pointers to handle options

Another use I have found for function pointers is using them to clean up some chunks of code where user selectable options may significantly alter what a function needs to do.


For example, you may write your game to support various command line options or other kind of user selectable option. Normally there is a little give and take between giving options and
maintaining code readability and speed of execution. However with function pointers you can overcome these problems quite easily and instead of having a slew of if statements to determine which
cryptically named function to call you can set the simply named function pointer at the start of the program, or when your options are reset, and not have to worry about cryptic names or slews of if
statements again.


Conclusion

After reading this you should have a pretty fair idea of how to incorporate function pointers into your code. I can't guarantee that you will increase your FPS but I think will be more readable
and will make your classes much easier to use. If you have any questions or comments you can e-mail me at griffenjam at hot mail dot com.








Comments

Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere where collaboration is valued above all else.




PARTNERS