UE4 智能指针和弱指针

本文来源:CSDN - 飞起的猪


一、序言

我们知道C++里面有自己的指针,但是在虚幻引擎中原生C++的指针在分配和释放内存时会产生一些问题,比如无法被虚幻进行回收,造成内存泄漏等问题,于是虚幻就衍生出了智能指针。虚幻智能指针库是 C++11 智能指针的自定义实现,旨在减轻内存分配和跟踪的负担。此实现包括行业标准共享指针、弱指针和唯一指针。它还添加了类似于不可为空的共享指针的共享引用。这些类不能与UObject系统一起使用,因为虚幻对象使用单独的内存跟踪系统,该系统针对游戏代码进行了更好的调整。

二、各个指针的含义

共享指针(TSharedPrt):共享指针拥有它引用的对象,无限期地阻止删除该对象,并最终在没有共享指针或共享引用,引用它时处理它的删除。共享指针可以为空,这意味着它不引用任何对象。任何非空共享指针都可以生成对其引用的对象的共享引用。

共享引用(TSharedRef):共享引用的作用类似于共享指针,因为它拥有它所引用的对象。它们在空对象方面有所不同;共享引用必须始终引用非空对象。因为共享指针没有这个限制,所以共享引用总是可以转换为共享指针,并且共享指针保证引用一个有效的对象。当您想要保证被引用的对象是非空的,或者如果您想要指示共享对象的所有权时,请使用共享引用。

弱指针(TWeakPtr):弱指针类似于共享指针,但不拥有它们引用的对象,因此不会影响其生命周期。这个属性非常有用,因为它打破了引用循环,但这也意味着弱指针可以随时变为空,而不会发出警告。出于这个原因,弱指针可以生成指向它引用的对象的共享指针,从而确保程序员临时安全地访问该对象。

唯一指针(TUniquePtr):唯一指针单独且明确地拥有它所引用的对象。由于给定资源只能有一个唯一指针,因此唯一指针可以转移所有权,但不能共享它。任何复制唯一指针的尝试都将导致编译错误。当唯一指针超出范围时,它会自动删除它引用的对象。

三、指针的用法

为了更好的使用指针,虚幻提供了几个帮助类和函数,使使用智能指针更容易、更直观。

TSharedFromThis 从TSharedFromThis添加AsShared或SharedThis函数派生您的类。这些函数使您能够获取TSharedRef到您的对象。
MakeShared和MakeShareable 从常规 C++ 指针创建共享指针。MakeShared在单个内存块中分配新的对象实例和引用控制器,但要求对象提供公共构造函数。MakeShareable效率较低,但即使对象的构造函数是私有的也可以工作,使您能够获得不是您创建的对象的所有权,并在删除对象时支持自定义行为。
StaticCastSharedRef和StaticCastSharedPtr 静态转换实用函数,通常用于向下转换为派生类型。
ConstCastSharedRef和ConstCastSharedPtr 将const智能参考或智能mutable指针分别转换为智能参考或智能指针。


四、使用智能指针的优缺点

优点:

  • std::Shared_Ptr不是在所有的平台上都可用。
  • 使得在所有的编译器和平台上更加一致性。
  • 可以和其他虚幻容器无缝协作。
  • 更好的控制平台特性,包括线程处理和优化。
  • 线程安全的功能。
  • 我们想在性能方面有更多的控制权(内敛函数,内存,虚函数等)。
  • 在不需要的时候不需要引入第三方依赖。

缺点:

  • 创建和复制智能指针比创建和复制原始 C++ 指针涉及更多开销。
  • 维护引用计数会增加基本操作的周期。
  • 一些智能指针比原始 C++ 指针使用更多内存。
  • 参考控制器有两个堆分配。使用MakeShared而不是MakeShareable避免第二次分配,并且可以提高性能。

五、案例测试

原生C++与智能指针之间的转化

智能指针之间的转化

TSharedFromThis()的用法:保留一个对对对象的弱引用,方便直接转化成共享引用AsShared();

class TaskA:public TSharedFromThis<TaskA>
{
public:
	int32 a;
    float b;
};
.CPP文件中测试
       TSharedPtr<TaskA>NewTest = MakeShareable(new TaskA());
	newtask->a;
	TaskA *NewTest1 = NewTest.Get();//解引用将智能指针转化成原生指针
	if (NewTest1)
	{
		NewTest1->AsShared();
	}
	TaskA *currentTask = new TaskA();//原生指针
	TSharedRef<TaskA> Task_c = currentTask->AsShared();

综合案例


版权声明:本文为CSDN博主「飞起的猪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43021038/article/details/125987920

最新文章