【UE数字孪生学习笔记】 Gameplay框架之TArray

声明:部分内容来自于b站,知乎,慕课,公开课等的课件,仅供学习使用。如有问题,请联系删除。

部分内容来自UE官方文档,博客等

TArray:虚幻引擎中的数组

虚幻引擎4(UE4)中最简单的容器类是 TArray。TArray 负责同类型其他对象(称为"元素")序列的所有权和组织。由于 TArray 是一个序列,其元素的排序定义明确,其函数用于确定性地操纵此类对象及其顺序。

TArray

TArray 是UE4中最常用的容器类。其速度快、内存消耗小、安全性高。TArray 类型由两大属性定义:元素类型和可选分配器。

元素类型是存储在数组中的对象类型。TArray 被称为同质容器。换言之,其所有元素均完全为相同类型。单个 TArray 中不能存储不同类型的元素。

分配器常被省略,默认为最常用的分配器。其定义对象在内存中的排列方式;以及数组如何进行扩展,以容纳更多的元素。若默认行为不符合要求,可选取多种不同的分配器,或自行编写。此部分将稍后讨论。

TArray 为数值类型。意味其与其他内置类型(如 int32 或 浮点)的处理方式相同。其设计时未考虑扩展问题,因此建议在实际操作中勿使用 新建(new) 和 删除(delete) 创建或销毁 TArray 实例。元素也为数值类型,为容器所拥有。TArray 被销毁时其中的元素也将被销毁。若在另一TArray中创建TArray变量,其元素将复制到新变量中,且不会共享状态。

创建和填充数组

如要创建数组,将其以此定义:

cpp 复制代码
	TArray<int32> IntArray;

此操作会创建用于存储整数序列的空白数组。元素类型是可根据普通C++值规则进行复制和销毁的数值类型,例如 int32、FString、TSharedPtr 等。由于无指定分配器,因此 TArray 将采用基于堆的默认分配器。此时尚未分配内存。

有多种填充 Tarray 的方法。一种方式是使用 Init 函数,将大量元素副本填入数组。

cpp 复制代码
    IntArray.Init(10, 5);
	// IntArray == [10,10,10,10,10]
 

Add 和 Emplace 函数用于在数组末尾新建对象:

cpp 复制代码
    TArray<FString> StrArr;
	StrArr.Add    (TEXT("Hello"));
	StrArr.Emplace(TEXT("World"));
	// StrArr == ["Hello","World"]
 

新元素添加到数组时,数组的分配器将根据需要分配内存。当前数组大小超出时,默认分配器将添加足够的内存,用于存储多个新元素。Add 和 Emplace 函数的多数效果相同,细微区别在于:

  • Add(或 Push)将元素类型的实例复制(或移动)到数组中。
  • Emplace 使用给定参数构建元素类型的新实例。

因此在 TArray 中,Add 将用字符串文字创建临时 FString,然后将该临时 FString 的内容移至容器内的新 FString 中;而 Emplace 将用字符串文字直接新建 FString。最终结果相同,但 Emplace 可避免创建临时文件。对于 FString 等非浅显数值类型而言,临时文件通常有害无益。

总体而言,Emplace 优于 Add,因此其可避免在调用点创建无需临时变量,并将此类变量复制或移动到容器中。根据经验,可将 Add 用于浅显类型,将 Emplace 用于其他类型。Emplace 的效率始终高于 Add,但 Add 的可读性可能更好。

利用 Append 可一次性添加其他 TArray 中的多个元素,或者指向常规C数组的指针及该数组的大小:

cpp 复制代码
	FString Arr[] = { TEXT("of"), TEXT("Tomorrow") };
	StrArr.Append(Arr, ARRAY_COUNT(Arr));
	// StrArr == ["Hello","World","of","Tomorrow"]

仅在尚不存在等值元素时,AddUnique 才会向容器添加新元素。使用以下元素类型的运算符检查等值性:运算符==:

cpp 复制代码
    StrArr.AddUnique(TEXT("!"));
	// StrArr == ["Hello","World","of","Tomorrow","!"]
 
	StrArr.AddUnique(TEXT("!"));
	// StrArr is unchanged as "!" is already an element
 

与 Add、Emplace 和 Append 相同,Insert 将在给定索引处添加单个元素或元素数组的副本:

cpp 复制代码
    StrArr.Insert(TEXT("Brave"), 1);
	// StrArr == ["Hello","Brave","World","of","Tomorrow","!"]

SetNum 函数可直接设置数组元素的数量。如新数量大于当前数量,则使用元素类型的默认构造函数新建元素:

cpp 复制代码
		StrArr.SetNum(8);

		// StrArr == ["Hello","Brave","World","of","Tomorrow","!","",""]
	 

如新数量小于当前数量,SetNum 将移除元素。移除元素的更多相关详情将稍后讨论:

cpp 复制代码
		StrArr.SetNum(6);

		// StrArr == ["Hello","Brave","World","of","Tomorrow","!"]

参考资料

https://dev.epicgames.com/documentation/zh-cn/unreal-engine/array-containers-in-unreal-engine

https://www.bilibili.com/video/BV1NH4y1g7N8

相关推荐
xiaoyalian21 分钟前
R语言绘图过程中遇到图例的图块中出现字符“a“的解决方法
笔记·r语言·数据可视化
Red Red2 小时前
网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
网络·笔记·学习·安全·web安全
贰十六3 小时前
笔记:Centos Nginx Jdk Mysql OpenOffce KkFile Minio安装部署
笔记·nginx·centos
知兀3 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
Natural_yz4 小时前
大数据学习17之Spark-Core
大数据·学习·spark
qq_172805594 小时前
RUST学习教程-安装教程
开发语言·学习·rust·安装
一只小小汤圆4 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
醉陌离4 小时前
渗透测试笔记——shodan(4)
笔记
虾球xz4 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
LateBloomer7774 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos