UE4 的 TSharedPtr、TWeakObjectPtr 模仿自 C++11 的 shared_ptr 、 weak_ptr 。

TSharedPtr

TSharedPtr 相当于对象的引用计数器。每当对 TSharedPtr 赋值一次,该 TSharedPtr 引用对象计数加一,当引用计数为0时,则该对象被自动销毁。

用法:

TSharedPtr<TestClass> ObjPtr = MakeShareable(new TestClass());

如果两个 TSharedPtr 相互赋值,则会导致对象永不释放,导致内存泄漏。

TSharedPtr无法对继承自UObject的对象指针进行计数,raw pointers才可以。

如果raw pointers想加入GC,那么指针所指对象必须继承FGCObject类。
因为C++11已经有一套 smart points,为了和UE4的垃圾回收区分开,所以TSharedPtr作用对象不包括raw pointers。

TWeakObjectPtr

TWeakObjectPtr 保持的对象不能防止被垃圾回收。若引用的对象在其他地方被销毁,则 TWeakObjectPtr 内部的指针自动将被置为NULL,TWeakObjectPtr::IsValid()会返回false。TSharedPtr 则没有这个作用。

Usage

Assignment

TWeakObjectPtr<AActor> MyWeakActor;
MyWeakActor = MyActor;

Get value

AActor* Actor = MyWeakActor.Get();

or

if(MyWeakActor.Get())
{
    ACharacter* Character = Cast<ACharacter>(MyWeakActor);
}

if MyActor has been destroyed, MyWeakActor.Get() would return nullptr

MyActor->Destroy();
bool IsValid = MyWeakActor.Get() != nullptr;    //false

if MyActor has been destroyed, Cast<AMyCharacter>(MyActor) would cause crash after a while, but Cast<AMyCharacter>(MyWeakActor) would not.

Remove in Array

Examples:

APawn* TestPawn = GetWorld()->SpawnActor<APawn>(MyPawnClass, FVector(100.f, 100.f, 0.f), FRotator::ZeroRotator);
APawn* MyPawn = GetWorld()->SpawnActor<APawn>(MyPawnClass, FVector(200.f, 200.f, 0.f), FRotator::ZeroRotator);

TestArray.Add(TWeakObjectPtr<APawn>(TestPawn));
TestArray.Add(TWeakObjectPtr<APawn>(MyPawn));

int Num = TestArray.Num();  // 2

TWeakObjectPtr<APawn> WeakPtr1(TestPawn);
TestArray.Remove(WeakPtr1);
int Num = TestArray.Num();  // 1

TWeakObjectPtr<APawn> WeakPtr2(TestPawn);
TestArray.Remove(WeakPtr2);
int Num2 = TestArray.Num(); // 1

TWeakPtr

Difference between TWeakPtr and TWeakObjectPtr:

TWeakObjectPtr is for weak pointers to UObjects, TWeakPtr for pointers to everything else.
Since UObjects are garbage collected and shared pointers are reference counted, we cannot have the same weak pointer type for all, unfortunately.

Difference between TWeakPtr and TWeakObjectPtr?
https://answers.unrealengine.com/questions/298868/difference-between-tweakptr-and-tweakobjectptr.html

TUniquePtr (Unique Pointers)

A Unique Pointer solely and explicitly owns the object it references. Since there can only be one Unique Pointer to a given resource, Unique Pointers can transfer ownership, but cannot share it. Any attempts to copy a Unique Pointer will result in a compile error. When a Unique Pointer is goes out of scope, it will automatically delete the object it references.

Reference

UE4 TSharedPtr和UObject的垃圾回收
http://www.v5xy.com/?p=808

There’s a Huge Difference, One Will Always Crash
https://answers.unrealengine.com/questions/48818/whats-the-difference-between-using-tweakobjectptr.html

what is a “weak object pointer”?
https://answers.unrealengine.com/questions/201186/what-is-a-weak-object-pointer.html

Unreal Smart Pointer Library
https://docs.unrealengine.com/en-US/Programming/UnrealArchitecture/SmartPointerLibrary/index.html


已识乾坤大,犹怜草木青。长空送鸟印,留幻与人灵。 —-马一浮《旷怡亭口占》