Enum vs StaticClass/TSubclassOf

Hi!

I’m a beginner dev and I’m wondering about the costs of storing and using Enum vs StaticClass/TSubclassOf.

For instance, this would be my base Pickup class.

class PROJECT_API APickupBase : public AActor

And this would be a Pickup type that inherits from that.

class PROJECT_API APickupType1: public APickupBase

Alright, so now I want to store that type in many, many different places in my project.

The number of pickups types are limited, so would I save any resource at all by using Enums instead (below) while storing that data (and then using it), or would it just add unnecessary calls to a dict that translates the Enum into the StaticClass?

Enum example:

UENUM()
enum class EPickupType : int16
{
None = 0 UMETA(DisplayName = "[INVALID]"),
Type1 = 1
};

EPickupType PickupType;

With a dict somewhere for when I need to translate it to instantiate the pickup:

const static TMap<EPickupType, TSubclassOf<APickupBase>> PickupTypeToClassMap = {
{EPickupType::Type1, APickupType1::StaticClass()}
};

Vs a straight:

TSubclassOf<APickupBase> PickupType;

I don’t need to use the TSubclassOf/StaticClass in all places I store the pickup type, that’s the major reason that led me to believe Enums might be cheaper here.

However, how much cheaper is it, really? Is it worth doing things this way at all? I mean, if all StaticClass calls return the very same UClass object as reference every time it’s called for the same class (and TSubclassOf stores it as a reference/pointer), it’s a single reference, so it wouldn’t be too costly. Except maybe when I’m comparing values, in which case Enums is probably cheaper?

So, help please?

Hello! Roughly speaking, TSubclassOf is UClass pointer and some additional meta (ctors and methods). UClass pointer size depends on memory and can be 32 or 64 bits. Enum can contain its base integer type, so you can easily compare them.

Thanks for the reply!

So if I have TSubclassOf<SomeClass> in two different places, and I assign them to SomeClass::StaticClass(), both will contain a 32/64bit pointer to the very same UClass, instead of instantiating new UClasses for each SomeClass::StaticClass() call? If so, that’s great.

However, comparing two UClass against each other is much costlier than comparing Enums, right? Or is it irrelevant unless we’re talking about tens of thousands of comparisons per tick?

Pointers are compared simply by their addresses, so it is also very effective. It is very simple to compare one UClass* and another UClass* (integer comparison). And one enum with another enum(integer comparison). But, it can be heavy to compare on UClass and another UClass (here are not pointers!)

Dont forget, that if you want to compare objects themselves and not their pointers you should dereference pointer first and only after that you can compare.

Thank you so much! You answered everything I wanted to know! Would you mind answering the topic itself so I can accept it? Or would you rather I just copy the things you said in an answer myself and accept it? Whatever is easier for you ^^