转自:https://dawnarc.com/2018/07/ue4-tsharedptr-tweakobjectptr-and-tuniqueptr/
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