C++ TObjectPtr<> as a return type, is it good practice?

I read over the documentation regarding migration to UE5 and recommended good practices when using pointers in UE5. It seems they really want us to use TObjectPtr, which is fine. The documentation recommends adding UPROPERTY() to each instance of a TObjectPtr<> to ensure it is seen by garbage collector. With this being said, is it safe/recommended to return a TObjectPtr<> in UE5 C++?

Migration guide - Unreal Engine 5 Migration Guide | Unreal Engine 5.4 Documentation | Epic Developer Community

Pointers reference - Smart Pointers in Unreal Engine | Unreal Engine 5.2 Documentation | Epic Developer Community

Thanks!

It should be fine just make sure to check if the object is Valid before accessing any of its members/functions.

You can always look at some of the built in engine functions as a reference. Returning a pointer is a common thing, what you do with it is where safety can be an issue if you don’t check for valid etc.

For TObjectPtr it’s very similar to your typical raw pointer but there are other advantages to using it. This forum post contains some good info on why you would wanna use it.

Returning TObjectPtr<> should be safe but not something I would recommend doing. TObjectPtr<> represents a lifetime dependency similar to standard c++ smart pointers, where the object referenced in the property should either not exist without the object holding it or the object itself depends on the referenced object, hence it not being GCed for as long as the reference exists.

We typically only use TObjectPtr<> in properties and then pass the objects around using raw pointers/references. In most functions, you don’t care about lifetimes since you are not freeing anything explicitly, it makes the signatures shorter/easier to read and you can convert between TObjectPtr<> and raw pointers either implicitly or easily using Get().

1 Like

I wouldn’t look at it as a smart pointer though, it’s very similar to a raw pointer and it behaves the same way in terms of garbage collection as indicated in the description.

This makes a lot of sense, thank you to all that replied. I had the same suspicion regarding using it as a return type but wanted to confirm. Seems like TObjectPtr<> should be reserved for class or object properties in which you need to ensure the pointer ref is registered with the GC and made nullptr when owner is destroyed (correct me if I’m wrong on this), as suggested by @KaidoomDev 's reply to my question.

For now, I’ll leave my functions set as:

AActor* foo()

rather than:

TObjectPtr<AActor> foo() (what I was confused if I should change or not)

Thanks!

[Marking this as solution as a summary, thanks all that replied]