[Question] UObject Pointer References

I understand how pointers in c++ work. I understand what weak pointers are. My question is, does a bare pointer to a UObject count as a reference count for an object stopping it being garbage collected?

Example class:

UCLASS()
class AMyActor : public AActor
{
	GENERATED_UCLASS_BODY()

public:

	UObject* MyObjectReference;

};

Does instantiating this class and assigning something to MyObjectReference count as a reference to the assigned object, stopping it being garbage collected, or do you need to use one of the TPtr templates?

I imagine that actors, specifically, probably won’t be garbage collected in the level until they are deleted, so what about other UObjects? If I defined my own UObject-derived class and assign it to a pointer, is that enough?

Edit: I use TWeakObjectPtr quite a lot where I don’t want it to be ref counted, but I want to make sure that I’m not missing something when I do want it to be.

A pointer to a UObject by itself will not be saved from garbage collection. You must mark that up with a UPROPERTY() so the appropriate metadata/reflection is generated to keep the object alive.

Properties give you lots of things “for free”. Automatic garbage collection is one of them. Of course you can have TWeakObjectPtr so that GC won’t consider this as ownership, and then you will check IsStale() and Get() it when you need it.

If you had a non UObject that needed to have a pointer to a UObject, UPROPERTY() wouldn’t work, but there are methods to ensure that an object is marked as alive come GC time.

UPROPERTY()
UObject* MyObjectReference;

Ah ha! Thanks a lot, Josh. :slight_smile:

One other question. Does that apply as well for TArrays?

E.g.

UPROPERTY()
TArray MyArray;

will stop everything in the array being gc’d?

TArrays of UObjects or UStructs that have UObjects in it will be safe, but you are responsible for the general memory cleanup of any TArray footprint that isn’t a UObject.

The idea is that UPROPERTY() adds the appropriate information about reachability/discoverability for objects so that the garbage collector can determine if an object is alive. A TArray MyThing; would leak memory if you didn’t free it yourself, with or without the UPROPERTY(). Arguably this wouldn’t even need to be a UPROPERTY().

UPROPERTY() also gives you visibility to the variables at runtime from the console window (assuming the var can be described as viewable types).

For example, you can do

~
displayall PlayerController PlayerState

and you will see all the player state objects in the game dynamically, because PlayerState is a UPROPERTY on PlayerController

similarly you can do

~
displayall PlayerState PlayerName

because PlayerName is an FString marked as a UPROPERTY and the engine knows how to display an FString

Great. Thanks. Exactly what I was looking for!