
Managed memory – smart pointers (TSharedPtr, TWeakPtr, TAutoPtr) to track an object
When people are afraid that they'll forget the delete
call for standard C++ objects they create, they often use smart pointers to prevent memory leaks. TSharedPtr
is a very useful C++ class that will make any custom C++ object reference-counted—with the exception of UObject
derivatives, which are already reference-counted. An alternate class TWeakPtr
is also provided for pointing to a reference-counted object with the strange property of being unable to prevent deletion (hence, "weak").

Tip
UObject
and it's derivative classes (anything created with NewObject
or ConstructObject
) cannot use TSharedPtr
!
Getting ready
If you don't want to use raw pointers and manually track deletes into your C++ code that does not use UObject
derivatives, then that code is a good candidate for using smart pointers such as TSharedPtr
, TSharedRef
, and the like. When you use a dynamically allocated object (created using the keyword new
), you can wrap it up in a reference-counted pointer so that deallocation happens automatically. The different types of smart pointers determine the smart pointer behavior and deletion call time. They are as follows:
TSharedPtr
: A thread-safe (provided you suppliedESPMode::ThreadSafe
as the second argument to the template) reference-counted pointer type that indicates a shared object. The shared object will be deallocated when there are no more references to it.TAutoPtr
: Non-thread-safe shared pointer.
How to do it...
We can demonstrate use of the four types of smart pointers referred to previously using a short code segment. In all of this code, the starting pointer can either be a raw pointer, or a copy of another smart pointer. All you have to do is take the C++ raw pointer and wrap it in a constructor call to any of TSharedPtr
, TSharedRef
, TWeakPtr,
or TAutoPtr
.
For example:
// C++ Class NOT deriving from UObject class MyClass { }; TSharedPtr<MyClass>sharedPtr( new MyClass() );
How it works…
There are some differences between weak pointers and shared pointers. Weak pointers do not have the capability to keep the object in memory when the reference count drops to 0.
The advantage of using a weak pointer (over a raw pointer) is that when the object underneath the weak pointer is manually deleted (using ConditionalBeginDestroy()
), the weak pointer's reference becomes a NULL
reference. This enables you to check if the resource underneath the pointer is still allocated properly by checking a statement of the form:
if( ptr.IsValid() ) // Check to see if the pointer is valid { }
There's more…
Shared pointers are thread-safe. This means that the underlying object can safely be manipulated on separate threads. Always remember that you cannot use TSharedRef
with UObject
s or UObject
derivatives—only on your custom C++ classes, or on your FStructures
can you use any of the TSharedPtr
, TSharedRef
, TWeakPtr
classes to wrap up a raw pointer. You must use TWeakObjectPointer
or UPROPERTY()
as a starting point to point to an object using a smart pointer.
You can use TAutoPtr
if you do not need the thread-safety guarantee of TSharedPtr
. TAutoPtr
will automatically delete an object when the number of references to it drops to 0.