【UE5 C++初学笔记】 03.智能指针
U++智能指针分为四类:
共享指针(TSharedPtr)、共享引用(TSharedRef)、弱指针(TWeakPtr(TSharedRef))、唯一指针(TUniquePtr)
关于智能指针的理解:
虚幻引擎的共享指针不用于指向UObject,UObject管理有专属的垃圾回收机制。智能指针中,共享指针主要是用来延长对象的生命周期,让其在有被引用的时候存在,不被引用的时候就销毁,可为空;共享引用类比共享指针,但是不可为空,共享引用可以隐式转换为共享指针,共享指针需要调用ToShareRef()函数转换为共享引用,共享指针转换为共享引用时要注意非空判定;弱指针是一个观察者,可以将共享指针转化为弱指针,不会改变指向对象的生命周期,因此弱指针引用的对象在使用时也可能被销毁,需要用Pin()转换为共享指针才能访问对象,同时,弱指针也用于打破共享指针的循环引用;唯一指针则主要用于控制指向对象的唯一所有权,只允许该唯一指针访问,指针超出作用域会自动删除对象,不应该与共享指针或共享引用混用。
一、共享指针和共享引用
初始化:
struct Struct1
{
int32 a = 1;
};
TSharedPtr<Struct1> SharedPtr0;//可以创建一个空白的共享指针。
TSharedPtr<Struct1> SharedPtr1(new Struct1());
TSharedRef<Struct1> SharedRef1(new Struct1());
TSharedPtr<Struct1> SharedPtr2 = MakeShared<Struct1>();
TSharedRef<Struct1> SharedRef2 = MakeShared<Struct1>();
重置:
共享指针可以通过Reset()或赋值nullptr来重置,此时如果没有别的共享指针指向原对象则会直接销毁原对象。
SharedPtr1.Reset();
SharedPtr = nullptr;
共享引用不支持该方法,共享引用设计为始终引用一个有效且非空的对象。
转移(原指针指向nullptr,浅拷贝(复制)的话就直接=):
SharedPtr2 = MoveTemp(SharedPtr1);//包含静态断言,强制在非常量左值上执行
SharedPtr2 = MoveTempIfPossible(SharedPtr1);
转换:
TSharedPtr<Struct1> SharedPtr2 = MakeShared<Struct1>();//MakeShared返回的是TSharedRef
if(SharedPtr1.IsValid())
{
SharedRef1 = SharedPtr1.ToShareRef();
}
对比、解引用、访问操作都和C++风格的智能指针一样,
共享指针或引用在构造时可输入lamda函数作为自定义删除器
void DestroyMyObjectType(FMyObjectType* ObjectAboutToBeDeleted)
{
// 此处添加删除代码。
}
// 这些函数使用自定义删除器创建指南指针。
TSharedRef<FMyObjectType> NewReference(new FMyObjectType(), [](FMyObjectType* Obj){ DestroyMyObjectType(Obj); });
TSharedPtr<FMyObjectType> NewPointer(new FMyObjectType(), [](FMyObjectType* Obj){ DestroyMyObjectType(Obj); });
二、弱指针
初始化:
TWeakPtr<Struct1> WeakPtr1(SharedPtr1);
复制和重置操作和共享指针相同,不必在意是否为空,使用完也可以进行重置。
访问:
if(WeakPtr.IsValid())
{
WeakPtr1.Pin()->a;//转化为共享指针后可进行访问操作
WeakPtr1.Pin().Get()->a;//Get()返回Struct1*裸指针
}
打破引用循环(引用虚幻引擎官方文档):
两个或多个对象使用智能指针保持彼此间的强引用时,将出现引用循环。在此类情况下,对象间会相互保护以免被删除。各对象固定被另一对象引用,因此对象无法在另一对象存在时被删除。如外部对象未对引用循环中对象进行引用,其实际上将出现泄漏。弱指针不会保留自身引用的对象,因此其可中断此类引用循环。要在未拥有对象时对其进行引用,并延长其寿命时,可使用软指针。
使用警告:
弱指针不应该用作Set或Map里的键,随时可能无效,IsValid()无法保证持续有效,应当使用Pin()访问。
更多推荐

所有评论(0)