Function Pointers

From Epic Wiki
Jump to: navigation, search

Overview

Original Author: Rama (talk)

Dear Community,

When you have a whole bunch of functions that you want to call, that are all related in some way,

you can make a function pointer array to quickly access and call a specific function by index!

My Example: 30 Behavior Functions

In my example, I have 30 behaviors that are all virtual functions as part of an AI system.

Each creature needs to implement the behavior in its own way, so the functions are virtual.

But in the AI class, I need to be able to say "run this behavior function" quickly and easily.

That's what function pointers enable you to do!


Special Thanks and C++ Note

You can easily find info on function pointers on the internet, but in UE4 classes you need to also specify the namespace, and I was having trouble with that part

Special thanks go to Steve Allison and other Epic Devs for offering the correct syntax!


C++ Code for UCLASS() Function Pointers

YourClass.h

#include "YourClass.generated.h"

#define BEHAVIORS_MAX 30

UCLASS()
class AYourClass : AActor //or any other class setup
{
	GENERATED_UCLASS_BODY()
	
public:
	
	//The Function Pointer Variable Type
	//Functions take in 0 parameters and return void
	typedef void (AYourClass::*FunctionPtrType)(void);
	
	//A static array of 30 Function Pointers
	FunctionPtrType BehaviorFunctions[BEHAVIORS_MAX];
	
	//Play a Behavior from the Function Pointer Array
	//	implementation does not vary in subclasses, so not virtual
	void PlayBehavior(int32 BehaviorIndex );
	
	//Initialize the array
	void InitBehaviors();
	
	//The actual functions which are implemented in subclasses
	//or this class itself
	virtual void PlayBehavior_Idle_LookLeftToRight();
	virtual void PlayBehavior_Idle_LookFullCircle();
	virtual void PlayBehavior_Idle_ScanUpDown();
	//...more functions
}

YourClass.cpp

#define LOOK_FULL_CIRCLE 0

#define SCAN_LEFT_TO_RIGHT 1

#define SCAN_UP_DOWN	  2
//... more function index defines to 29

void AYourClass::InitBehaviors()
{
	BehaviorFunctions[LOOK_FULL_CIRCLE] = &AYourClass::PlayBehavior_Idle_LookFullCircle;
	BehaviorFunctions[SCAN_LEFT_TO_RIGHT] = &AYourClass::PlayBehavior_Idle_LookLeftToRight;
	BehaviorFunctions[SCAN_UP_DOWN] = &AYourClass::PlayBehavior_Idle_ScanUpDown;
	//...more functions
}

void AYourClass::PlayBehavior_Idle_LookLeftToRight(){}
void AYourClass::PlayBehavior_Idle_LookFullCircle(){}
void AYourClass::PlayBehavior_Idle_ScanUpDown(){}
//...rest of functions


void AYourClass::PlayBehavior(int32 BehaviorIndex )
{
	//valid range check
	if (BehaviorIndex >= BEHAVIORS_MAX || BehaviorIndex < 0) return;
	//~~
	
	//Special Thanks to Epic for this Syntax
	(this->* (BehaviorFunctions[BehaviorIndex]))();
	
	//the above line plays the appropriate function based on the passed in index!
}

Syntax Complexity Comparison

this same sort of setup, without function pointers, would either have been a switch statement, or a series of if elses.

Supposing there were actually 30 entries you can see why a function pointer array simplifies all this!

this

//Without function pointers
if(BehaviorIndex == SCAN_LEFT_TO_RIGHT)
	PlayBehavior_Idle_LookLeftToRight();
	
else if (BehaviorIndex == LOOK_FULL_CIRCLE)
	PlayBehavior_Idle_LookFullCircle();
	
else if (BehaviorIndex == SCAN_UP_DOWN)
	PlayBehavior_Idle_ScanUpDown();
//...
//...
//and much much more ...

becomes this!

//With Function Pointers
//Special Thanks to Epic for this Syntax
(this->* (BehaviorFunctions[BehaviorIndex]))();

//that's it! nothing else!!!!

Summary

Thanks to Epic I can now present to you the correct C++ syntax for using UCLASS-specific function pointers!

Rama (talk)