容器是一种类,它的主要功能是存储数据集合。最常见的这些类包括 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元素的TArray
TArray<AActor*> ActorArrayFromSet = ActorSet.Array();