UE4 智能指针

简介

虚幻智能指针库为C++11智能指针的虚幻自定义实现,用于非UObject的数据对象。
虚幻Objects使用更适合游戏代码的单独内存追踪系统,不适合用智能指针,请使用对象处理。

智能指针类型

TSharedPtr

共享指针:共享指针拥有其引用的对象,防止该对象被删除,并在无共享指针或共享引用(见下文)引用其时,删除该对象。共享指针可为空,意味其不引用任何对象。
非空共享指针可生成共享引用。
创建共享指针

//MakeSHared 创建共享引用,隐式转换为共享指针。
TSharedPtr<FMyObjectType> NewSharedPtr = MakeShared<FMyObjectType>();

TSharedPtr<FMyObjectType> UnassignedSharedPtr;

//MakeShareable 效率较低,但即使对象的构造函数为私有,其仍可运行。
TSharedPtr<FMyObjectType> NewSharedPtr = MakeShareable<FMyObjectType>();

TSharedRef

共享引用(就是非空共享指针):与共享指针类似,固定引用非空对象。
创建共享引用

//创建共享引用,共享引用不可为空,因此初始化必须要有数据对象。

TSharedRef<FMyObjectType> NewReference = MakeShared<FMyObjectType>();


//错误示范:
//以下两者均不会编译:
TSharedRef<FMyObjectType> UnassignedReference;
TSharedRef<FMyObjectType> NullAssignedReference = nullptr;
//以下会编译,但如NullObject实际为空则断言。
TSharedRef<FMyObjectType> NullAssignedReference = NullObject;

TSharedPtr 和 TSharedRef相互转换

//共享引用可隐式转换为共享指针
TSharedPtr<FMyObjectType> MySharedPointer = MySharedReference;

//共享指针转换为共享引用前,确保共享指针为有效。
If (MySharedPointer.IsValid())
{
    MySharedReference = MySharedPointer.ToSharedRef();
}

两个共享引用可比较,相等表示同一对象。

if (ReferenceA == ReferenceB)
{
    // ...
}

TWeakPtrSharedPtr

弱指针:与共享指针类似,但不拥有引用的对象,不影响其生命周期,不会阻止引用的对象被销毁。
可以为共享指针创建弱指针,不会影响到对象。

//分配新的数据对象,并创建对其的强引用。
TSharedRef<FMyObjectType> ObjectOwner = MakeShared<FMyObjectType>();
//创建指向新数据对象的弱指针。
TWeakPtr<FMyObjectType> ObjectObserver(ObjectOwner);

//假设ObjectOwner是其对象的唯一拥有者,ObjectOwner停止引用该对象时,该对象将被销毁。
ObjectOwner.Reset();
//ObjectOwner引用空对象,因此Pin()生成的共享指针将也将为空。被视为布尔时,空白共享指针的值为false。
if (ObjectObserver.Pin())//检查有效的首选方法
{
    //只当ObjectOwner非对象的唯一拥有者时,此代码才会运行。
    check(false);
}

//可以安全复制
TWeakPtr<FMyObjectType> AnotherObjectObserver = ObjectObserver;

//可通过将弱指针设为nullptr进行重置。
ObjectObserver = nullptr;
//也可使用重置函数。
AnotherObjectObserver.Reset();

转换为共享指针。

//获取弱指针中的共享指针,并检查其是否引用有效对象。
if (TSharedPtr<FMyObjectType> LockedObserver = ObjectObserver.Pin())
{
    //共享指针仅在此范围内有效。
    //该对象已被验证为存在,而共享指针阻止其被删除。
    LockedObserver->SomeFunction();
}

TUniquePtr

唯一指针:显式拥有引用的对象。
注:对唯一指针引用的对象进行共享指针或共享引用的操作十分危险。即使其他智能指针继续引用该对象,此操作不会取消唯一指针自身被销毁时删除该对象的行为。同样,不应为共享指针或共享引用引用的对象创建唯一指针。

优缺点

优点:
  • 防止内存泄漏
    共享引用不存在时,智能指针(弱指针除外)会自动删除对象。

  • 弱引用
    弱指针会中断引用循环并阻止悬挂指针。

  • 可选择的线程安全
    虚幻智能指针库包括线程安全代码,可跨线程管理引用计数。如无需线程安全,可用其换取更好性能。

//线程安全版本
TSharedPtr<T, ESPMode::ThreadSafe>

TSharedRef<T, ESPMode::ThreadSafe>

TWeakPtr<T, ESPMode::ThreadSafe>

TSharedFromThis<T, ESPMode::ThreadSafe>
  • 运行时安全
    共享引用从不为空,可固定随时取消引用。

  • 授予意图
    可轻松区分对象所有者和观察者。

  • 内存
    智能指针在64位下仅为C++指针大小的两倍(加上共享的16字节引用控制器)。唯一指针除外,其与C++指针大小相同。

缺点:
  • 效率增加

其它的智能指针

TWeakObjectPtr

与TWeakObjectPtr类似,针对UObject,在不能使用反射的情况下可以使用TWeakObjectPtr, 防止悬空指针。

	//UObject* MyUObject
	TWeakObjectPtr<AActor> weakObjectPtr;
	TWeakObjectPtr<AActor> weakObjectPtr(MyUObject);
	TWeakObjectPtr<AActor> weakObjectPtr = MyUObject;
发布了83 篇原创文章 · 获赞 65 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/lixpjita39/article/details/105443213
今日推荐