Important: there seem to be multiple ways to check for validity of a UObject.
Let's assume, we have an AActor* and want to get the location.
AActor* MyEmptyActor = {};
FVector ActorLocation;
Variant 1: C++ automatic check
if (MyEmptyActor)
{
ActorLocation = MyEmptyActor->GetActorLocation();
}
Variant 2: C++ nullptr check
if (MyEmptyActor != nullptr)
{
ActorLocation = MyEmptyActor->GetActorLocation();
}
Variant 3: C++ Unreals' checks from Pointer (also IsValidLowLevelFast)
if (MyEmptyActor->IsValidLowLevel())
{
ActorLocation = MyEmptyActor->GetActorLocation();
}
Variant 4: C++ Unreals' IsValid of Pointer (uses slow validity check, IsValidLowLevel might be faster)
if (IsValid(MyEmptyActor))
{
ActorLocation = MyEmptyActor->GetActorLocation();
}
Now while I'm still trying to figure out more details on when to use what, what I can say so far is, that using Variant 1 or 2, they're C++ native and can have issues. For example, Variant 3 and 4 seem to check, if a Pointer will is pending kill or will be garbage collected in the future (next frame/next game loop).
If something might be garbage collected or will be killed, use Variant 3 or 4. If not, Variant 1 or 2 should be just fine.
Since regular Pointers are different from UObjects, you can simply just use the default C++ methods.
int64 MyInt = 42;
int64* MyIntPtr = &MyInt;
Variant 1: C++ automatic check
if (MyIntPtr)
Variant 2: C++ nullptr check
if (MyIntPtr != nullptr)
Sometimes, if a check for a nullptr, a variable, a value etc. is false, you want to crash the engine.
Why you may ask? Maybe you don't want too many exception to be handled, simplify code or just use it for debugging purposes.
In order to do that, here's an example:
AActor* MyEmptyActor = {};
check(MyEmptyActor != nullptr);
If the MyEmptyActor is not a null-pointer, the code will continue.
Here though it actually is a null-pointer, so the engine will just crash.
If you want to crash the Engine while showing an Error, use the following as an example:
AActor* MyEmptyActor = {};
checkf(MyEmptyActor != nullptr, TEXT("Pointer to Actor is null!"));
If you want to crash the Engine while showing an Error with a custom FString, use the following as an example:
AActor* MyEmptyActor = {};
checkf(MyEmptyActor != nullptr, TEXT("Pointer to Actor is null (for %s)!"), *this->GetName());
Important Note: the FString at the end has to be de-references by using the "*" in front of it. Otherwise it will return the following when compiling:
"Error C4840 : non-portable use of class 'FString' as an argument to a variadic function"