TSharePtr智能指针
#1. 智能指针是什么
struct MyStruct
{
FString MyString;
int32 MyInt32;
};
MyStruct* Struct = new MyStruct();
Struct->MyString = TEXT("TEST");
Struct->MyInt32 = 1;
delete Struct;
TSharedPtr<MyStruct> SharePtr = MakeShareable(new MyStruct());
SharePtr->MyString = TEXT("TEST");
SharePtr->MyInt32 = 1;
智能指针是自动引用Object计数,有引用的时候+1,没有引用的时候-1,当引用为0的时候销毁Object, 帮我们管理指针,不需要我们手动释放内存,程序也安全运行
#2. TSharePtr的作用范围 我们知道,UnrealEngine有一套自己的反射机制,以及一套UObject管理体系,UObject本身就具有管理内存的功能, 那么UObject可以使用TSharePtr吗,不可以的!
UItemHolder* Holder = NewObject<UItemHolder>();
TSharedPtr<UItemHolder> HolderPtr = MakeShareable(Holder);
HolderPtr->StrIpPort = TEXT("TEST");
TSharePtr的作用范围是原生指针RawPointer
#3. 使用注意
Objects would never be destroyed if two TSharedPtr, which are reference to a same object, were assigned to each other, resulting a memory leak.
不能使用2个智能指针指向同一个对象,会造成内存泄漏,建议使用方法 MakeShareable(new MyStruct()); 在方法参数里面直接new出来RawPointer
TWeakObjectPtr和TWeakPtr TWeakObjectPtr是作用UnrealEngine中UObject的WeakPtr,其作用: 可以忽略一个对象是否还有效的判断情况下,直接使用该对象,而程序安全执行; TWeakObjectPtr是弱对象指针,已经对对象进行了包装,使用的时候更安全; 比如我拿到了AI对象,但不确定该AI是否被其他玩家打死,这里就可以使用弱指针
UItemHolder* Holder = NewObject<UItemHolder>();
TWeakObjectPtr<UItemHolder> WeakHolder1 = Holder;
TWeakObjectPtr<UItemHolder> WeakHolder2(Holder);
if (WeakHolder2.IsValid())
{
UItemHolder* ItemHolder = WeakHolder1.Get();
ItemHolder->StrIpPort = TEXT("TEST");
}
使用的时候,通过包装IsValid()判断是否有效,通过Get()方法来获取包装实例
附:TWeakPtr TWeakPtr的作用是除UObject之外的对象 TObjectWeakPtr是只作用于UObject的对象
TWeakObjectPtr works for weak pointers of UObjects, TWeakPtr works 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.
TUniquePtr 唯一指针在内存中是唯一的,和面向对象语言的单列不同,TUniquePtr是指针唯一,指针指向的对象 是可以动态变更的,但不能被共享,可以当作单列来使用 TUniquePtr没有约束范围,UObject和RawPointer都可以使用

struct MyStruct
{
MyStruct(FString InStr, int32 InInt)
{
this->MyString = InStr;
this->MyInt32 = InInt;
}
FString MyString;
int32 MyInt32;
};
TUniquePtr<MyStruct> UniqueHolder = MakeUnique<MyStruct>(TEXT("TEST"), 1);
TUniquePtr<MyStruct> UniqueHolder = MakeUnique<MyStruct>(TEXT("TEST"), 1);
UniqueHolder = MakeUnique<MyStruct>("TEST2", 2);
GLog->Logf(L"----------%d", UniqueHolder->MyInt32);
可以动态变更指针指向的对象,但该对象在内存中是唯一的,第一个就给回收了
TUniquePtr和TQuene
TQueue<TUniquePtr<MyStruct>> QueueMyStruct;
TUniquePtr<MyStruct> Struct = MakeUnique<struct MyStruct>(L"TEST", 1);
QueueMyStruct.Enqueue(MoveTemp(Struct));
TUniquePtr<MyStruct> Buffer;
QueueMyStruct.Dequeue(Buffer);
TUnique和TArray
TArray<TUniquePtr<MyStruct>> MyStructs;
TUniquePtr<MyStruct> UniqueStruct = MakeUnique<MyStruct>(TEXT("CAT"), 1);
MyStructs.Add(MoveTemp(UniqueStruct));
TUniquePtr<MyStruct> Struct = MyStructs.Pop();
GLog->Logf(L"----------%d", Struct->MyInt32);
参考资料 [UE4] TSharedPtr, TWeakObjectPtr and TUniquePtr unreal-unique-pointer UE4 TSharedPtr和UObject的垃圾回收 There’s a Huge Difference, One Will Always Crash what is a “weak object pointer”? Unreal Smart Pointer Library
struct MyStruct
{
MyStruct(FString InStr, int32 InInt)
{
this->MyString = InStr;
this->MyInt32 = InInt;
}
FString MyString;
int32 MyInt32;
};
void AUnrealPtrTest::BeginPlay()
{
Super::BeginPlay();
TArray<TUniquePtr<MyStruct>> MyStructs;
TUniquePtr<MyStruct> UniqueStruct = MakeUnique<MyStruct>(TEXT("CAT"), 1);
MyStructs.Add(MoveTemp(UniqueStruct));
TUniquePtr<MyStruct> Struct = MyStructs.Pop();
GLog->Logf(L"----------%d", Struct->MyInt32);
TUniquePtr<MyStruct> UniqueHolder = MakeUnique<MyStruct>(TEXT("TEST"), 1);
UniqueHolder = MakeUnique<MyStruct>("TEST2", 2);
GLog->Logf(L"----------%d", UniqueHolder->MyInt32);
TQueue<TUniquePtr<MyStruct>> QueueMyStruct;
TUniquePtr<MyStruct> Struct = MakeUnique<struct MyStruct>(L"TEST", 1);
QueueMyStruct.Enqueue(MoveTemp(Struct));
TUniquePtr<MyStruct>* Peek1 = MoveTemp(QueueMyStruct.Peek());
QueueMyStruct.Pop();
TUniquePtr<MyStruct> Buffer;
QueueMyStruct.Dequeue(Buffer);
GLog->Logf(TEXT("--------- %s %d"), *Buffer->MyString, Buffer->MyInt32);
TWeakObjectPtr<UItemHolder> WeakHolder1 = Holder;
TWeakObjectPtr<UItemHolder> WeakHolder2(Holder);
if (WeakHolder2.IsValid())
{
UItemHolder* ItemHolder = WeakHolder1.Get();
ItemHolder->StrIpPort = TEXT("TEST");
}
UItemHolder* Holder = NewObject<UItemHolder>();
TSharedPtr<UItemHolder> HolderPtr = MakeShareable(Holder);
HolderPtr->StrIpPort = TEXT("TEST");
MyStruct* Struct = new MyStruct();
Struct->MyString = TEXT("TEST");
Struct->MyInt32 = 1;
delete Struct;
TSharedPtr<MyStruct> SharePtr = MakeShareable(new MyStruct());
SharePtr->MyString = TEXT("TEST");
SharePtr->MyInt32 = 1;
}
|