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;
}
|