Operator Overloads
Contents
Overview
Dear Community,
Sooooo
This is one reason why I love UE4 C++ so much!
We can do
anything
!
Below is the C++ code for making two operators that I've overloaded for use with an FString and a Float
Code Simplification
This enables me to go from
(Str is a FString)
Str = FString::SanitizeFloat(TheFloat);
to
Str <<= TheFloat;
UE4 String Stream
Using the code I am sharing with you below, I can also now create a UE4 String Stream! Streaming in Float values to Str like this!
Str = "";
Str << Float1 << Float2 << Float3;
Without Custom C++ Operators
for reference to do the above without my operators I would have to do this
Str = ""
Str += FString::SanitizeFloat(Float1);
Str += " ";
Str += FString::SantizeFloat(Float2);
Str += " ";
Str += FString::SanitizeFloat(Float3);
Global Scope
Please note you must define the operators at the global scope, so whatever .h you put them, dont include any "::" like MyClass::etc
FORCEINLINE
FORCEINLINE is a requirement for operator overloads if you want to be able to easily define them in a way that the UE4 compiler will like even when you have code split across multiple .cpp chunks!
With operator overloads you can either define them in one place, or use FORCEINLINE, and FORCEINLINE is the much easier approach when multiple header include appearances are involvedĀ :)
The C++
//Str float
FORCEINLINE FString& operator<<(FString &Str, const float& Value )
{
if(Str.Len() > 0) Str += " ";
Str += FString::SanitizeFloat(Value);
return Str;
}
FORCEINLINE FString& operator<<=(FString &Str, const float& Value )
{
Str = FString::SanitizeFloat(Value);
return Str;
}
Overloading Comparison Operators
Sometimes, you will want to overload a comparison operator for a special type of struct or class. Every comparison operator must return a boolean return value. Overloading comparison operators can be useful for determining if two objects are the same object based on a particular property rather than pointer reference. If you store a list of actors within a TArray, you may want those objects to be sorted by some particular property. If you overload the "<" operator, you can now call "sort()" on your TArray and the sort method will sort based off your "<" operator logic.
C++ Example
Let's say you have a custom struct for storing a list of creatures and their associated 'aggro' values. Each creature has a TArray which contains a list of sensed creatures and their associated aggro values. Each tick, your creature will try to resense all nearby creatures and update this aggro value data. If the list already contains an aggro record, we want to update the existing record rather than adding a new one. Once all aggro records have been updated, we want to call "sort()" on the creatures list of aggro records.
USTRUCT(BlueprintType)
struct FAggroData
{
GENERATED_USTRUCT_BODY()
public:
/*Sort Key: This is the aggro value for this enemy*/
UPROPERTY(BlueprintReadWrite, Category = "Aggro")
int32 Aggro;
/*This is the enemy we sensed*/
UPROPERTY(BlueprintReadWrite, Category = "Aggro")
ABaseCreature* Enemy;
/*This is the last known position of the enemy*/
UPROPERTY(BlueprintReadWrite, Category = "Aggro")
FVector LastSensePosition;
/*This is the last known velocity of the enemy*/
UPROPERTY(BlueprintReadWrite, Category = "Aggro")
FVector LastSenseVelocity;
/*This is how old the last sense time was*/
UPROPERTY(BlueprintReadWrite, Category = "Aggro")
float LastSenseAge;
//override the "<" operator so that this object can be sorted
FORCEINLINE bool operator<(const FAggroData &Other) const
{
return Aggro < Other.Aggro;
}
//check to see if the aggro record matches another aggro record by overloading the "==" operator.
FORCEINLINE bool operator==(const FAggroData &Other) const
{
return Enemy == Other.Enemy;
}
};
//ABaseCreature Class header:
TArray<FAggroData> SensedEnemies;
//ABaseCreature Tick:
//This will sort the list of sensed enemies based on the overloaded "<" operator. In this case, our sort
//scheme will put the creature with the highest aggro at the very front of the list. If we want to change the sort
//order, we can just swap the operands in the "<" operator overload
SensedEnemies.Sort();
Summary
With these operators in your code, no more
Str = FString::SanitizeFloat(TheFoat);
you can just do
Str <<= TheFloat;
Yay!
(
)