容器是一种类,它的主要功能是存储数据集合。最常见的这些类包括 TArray、TMap 和 TSet。每个类都会自动调节大小,因此增长到您所需的大小。
Containers完整主题:容器API
TArray
在所有三个容器中,在虚幻引擎4中将会使用的主要容器是TArray,它的功能与 std::vector 十分相似,但会提供更多功能。以下是一些常见操作:
TArray<AActor*> ActorArray = GetActorArrayFromSomewhere();// 告知当前ActorArray中存储了多少个元素(AActor)。int32 ArraySize = ActorArray.Num();// TArray基于0(第一个元素将位于索引0处)int32 Index = 0;// 尝试检索给定索引处的元素AActor* FirstActor = ActorArray[Index];// 在数组末尾添加新元素AActor* NewActor = GetNewActor();ActorArray.Add(NewActor);// 在数组末尾添加元素,但前提必须是该元素尚不存在于数组中ActorArray.AddUnique(NewActor); // 不会改变数组,因为已经添加了NewActor。// 从数组中移除"NewActor"的所有实例ActorArray.Remove(NewActor);// 移除指定索引处的元素// 索引之上的元素将下移一位来填充空白空间ActorArray.RemoveAt(Index);// 更高效版本的"RemoveAt",但不能保持元素的顺序ActorArray.RemoveAtSwap(Index);// 移除数组中的所有元素ActorArray.Empty();
TArray 添加了对其元素进行垃圾回收的好处。这样会假设 TArray 存储了 UObject 派生的指针。
UCLASS()class UMyClass : UObject{GENERATED_BODY();// ...UPROPERTY()AActor* GarbageCollectedActor;UPROPERTY()TArray<AActor*> GarbageCollectedArray;TArray<AActor*> AnotherGarbageCollectedArray;};
TMap
TMap 是键-值对的集合,类似于 std::map。TMap 具有一些根据元素键查找、添加和移除元素的快速方法。您可以使用任意类型来表示键,因为它定义有 GetTypeHash 函数,我们稍后将进行介绍。
假设您创建了一个基于网格的棋盘游戏,并需要存储和查询每一个正方形上的内容。TMap 会为您提供一种简单的可用方法。如果棋盘较小,并且尺寸不变,那么或许会有更有效的方法来达到此目的,但在此示例中,我们假设了一个尺寸较大、带有少量棋子的棋盘。
enum class EPieceType{King,Queen,Rook,Bishop,Knight,Pawn};struct FPiece{int32 PlayerId;EPieceType Type;FIntPoint Position;FPiece(int32 InPlayerId, EPieceType InType, FIntVector InPosition) :PlayerId(InPlayerId),Type(InType),Position(InPosition){}};class FBoard{private:// 通过使用TMap,我们可以按位置引用每一块TMap<FIntPoint, FPiece> Data;public:bool HasPieceAtPosition(FIntPoint Position){return Data.Contains(Position);}FPiece GetPieceAtPosition(FIntPoint Position){return Data[Position];}void AddNewPiece(int32 PlayerId, EPieceType Type, FIntPoint Position){FPiece NewPiece(PlayerId, Type, Position);Data.Add(Position, NewPiece);}
TSet
TSet 存储唯一值集合,类似于 std::set。虽然通过 TArray 可通过其 AddUnique 和 Contains 方法支持类似集的行为,TSet 可以更快的实现这些运算且不会自动添加非独有元素。
TSet<AActor*> ActorSet = GetActorSetFromSomewhere();int32 Size = ActorSet.Num();// 向集添加元素,但前提是集尚未包含这个元素AActor* NewActor = GetNewActor();ActorSet.Add(NewActor);// 检查元素是否已经包含在集中if (ActorSet.Contains(NewActor)){// ...}// 从集移除元素ActorSet.Remove(NewActor);// 从集移除所有元素ActorSet.Empty();// 创建包含TSet元素的TArrayTArray<AActor*> ActorArrayFromSet = ActorSet.Array();
