There are actually two different implementations of UClass::IsChildOf
(which is used by IsA
).
See Engine Source on GitHub
https://github.com/EpicGames/UnrealEngine/blob/d94b38ae3446da52224bedd2568c078f828b4039/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h#L480
https://github.com/EpicGames/UnrealEngine/blob/99b6e203a15d04fc7bbbf554c421a985c1ccb8f1/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp#L2197
The implementation is chosen like
#if UE_EDITOR || HACK_HEADER_GENERATOR
// On editor, we use the outerwalk implementation because BP reinstancing and hot reload
// mess up the struct array
#define USTRUCT_FAST_ISCHILDOF_IMPL USTRUCT_ISCHILDOF_OUTERWALK
#else
#define USTRUCT_FAST_ISCHILDOF_IMPL USTRUCT_ISCHILDOF_STRUCTARRAY
#endif
The USTRUCT_ISCHILDOF_STRUCTARRAY implementation caches an array of superstructs and the number of bases in the constructor of UStruct
. Then the actual IsChildOfUsingStructArray
implementation needs to compare only the number of bases as well as whether `` has the given Parent
at the corresponding index in its array of superstructs.
See Engine Source on GitHub
https://github.com/EpicGames/UnrealEngine/blob/99b6e203a15d04fc7bbbf554c421a985c1ccb8f1/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp#L4347
https://github.com/EpicGames/UnrealEngine/blob/d94b38ae3446da52224bedd2568c078f828b4039/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h#L271