虚幻C++中的细节之枚举类型(enum)

这篇具有很好参考价值的文章主要介绍了虚幻C++中的细节之枚举类型(enum)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

虚幻引擎中的代码部分实现了一套反射机制,为c++代码带了更多方便的特性。本篇文章将会着眼于其中更加细节的部分——虚幻中的enum。

在虚幻风格的代码中,我们经常能使用这样的方法来创建枚举类型:

UENUM(BlueprintType)
enum class EMyEnum : uint8
{
    Option1 UMETA(DisplayName = "Option 1"),
    Option2 UMETA(DisplayName = "Option 2"),
    Option3 UMETA(DisplayName = "Option 3")
};

似乎有一些c++的影子,但又好像有一些不一样的部分。它有基本c++的框架,但又有一些额外的东西。如果你对c++很熟悉,那再好不过。只需要始终把握一点,一切还是源于c++,额外的内容的目的是将该类型加入到反射系统中,使其支持序列化,使其能够支持蓝图编辑。

一、原生c++的枚举类型

我们来先将上面的例子简化一下

enum EMyEnum
{
    Option1,
    Option2,
    Option3
};

这是我们最熟悉的枚举创建方法,EMyEnum是枚举的名字。

下面是它一般的使用方式

// Example use of the enum
void MyFunction()
{
    EMyEnum MyOption = Option1;
    if (MyOption == Option2)
    {
        // Do something
    }
}

接下来,我们一点一点为它扩展。

关键字class

首先添加关键字class

enum class EMyEnum
{
    Option1,
    Option2,
    Option3
};

在这个例子中,我们的枚举类型EMyEnum有三个具体的选项:Option1Option2Option3。其中class关键字的作用是说明这是一个有作用范围(作用域)的枚举(scoped enum),意思是枚举的值需要在枚举类型的作用范围内使用,具体如下:

// Example use of the enum
void MyFunction()
{
    EMyEnum MyOption = EMyEnum::Option1;
    if (MyOption == EMyEnum::Option2)
    {
        // Do something
    }
}
int8 - 枚举的基础类型(underlying type

可以利用int8确定枚举值的基本类型

enum class EMyEnum : int8
{
    Option1,
    Option2,
    Option3
};

这意味着每个枚举值都会以一个8位的整型值来表示。其他可用基本类型还有uint8uint16uint32int16int32等等。

那这有什么用呢?比如说希望判断枚举值是否在某个范围内,或者是多个枚举值之间进行比较的时候。

下面看一个具体的例子

enum class EDamageType : uint8
{
    Blunt,
    Piercing,
    Fire,
    Ice,
    Electric,
    Poison
};

我们创建了一个表示伤害类型的枚举,当然从游戏的层面来讲,枚举值可能远远不止这些。

这里,我们可以利用><符号来判断枚举值是否在一个范围内,比如

EDamageType DamageType = EDamageType::Fire;

if (DamageType < EDamageType::Electric)
{
    // Do something for non-electric damage types
}
else
{
    // Do something for electric damage type
}

例子中,只要待判断的伤害类型属于BluntPiercingFireIce中的任何一个,判断条件都将成立,因为他们都小于Electric

更直观的,我们将每个枚举值的默认uin8都写出来

enum class EDamageType : uint8
{
    Blunt = 0,
    Piercing = 1,
    Fire = 2,
    Ice = 3,
    Electric = 4,
    Poison = 5
};

在进行比较或者范围判定的时候,实际上是这些枚举值背后的数字在进行判断。

当然,也可以不使用默认值而用任意指定的值,比如

enum class EDamageType : uint8
{
    Blunt = 100,
    Piercing = 200,
    Fire = 300,
    Ice = 400,
    Electric = 500,
    Poison = 600
};

可以使用static_castreinterpret_cast来进行枚举类型和其基础类型之间的显示转换

EDamageType DamageType = EDamageType::Fire;
uint8 DamageTypeValue = static_cast<uint8>(DamageType);

那么如果不指定基本类型会怎么样?像一开始那样直接将这个省略会有什么结果?

答案是编译器会根据枚举值自动为它挑选合适的基本类型,所以似乎省略也没有什么不妥,甚至为书写方便了不少。但是还是推荐在书写的时候指明基本类型,否则可能会有一些类型匹配方面的问题,亦或是出现一些无法预测的行为。

二、枚举类型的灵活运用

除了上面介绍的特性和基本应用,枚举还有一些其他好玩的用法。

位运算

利用位运算,可以快捷得将枚举值分配为以2为系数的等比数列,从而可以将枚举值表示为二进制码的组合,比如:

enum class EMyFlags : uint8
{
    None = 0,
    Flag1 = 1 << 0,
    Flag2 = 1 << 1,
    Flag3 = 1 << 2,
    Flag4 = 1 << 3,
    Flag4 = 1 << 5,
    All = Flag1 | Flag2 | Flag3 | Flag4,
};

在这个例子中,每个标志都进行左移运算,即每一个值都是前一个值的2倍。可以利用位运算符号(|,&,^)对这些枚举值进行组合。All就是所有标志组合的结果,将它与其中某个枚举值进行&运算,即可判断它是否包含该枚举值

EMyFlags MyFlag = EMyFlags::Flag1;
if (EMyFlags::All & MyFlag)
{
	// Do something
}

这里的结果自然是通过的。

枚举循环遍历

c++ 11的新特性中,可以对枚举类型的值使用循环遍历,如

for (EMyEnum Value : TEnumRange<EMyEnum>())
{
    // Do something with Value
}

在这个例子中,TEnumRange模板提供了一种遍历所有EMyEnum的枚举值的方式。

三、虚幻风格的枚举类型

虚幻在基础c++枚举的基础上,也加入了自己风格的代码,这自然也为它添加了更多的功能和特性。

这里以一个游戏中典型的枚举为例

UENUM(BlueprintType)
enum class EWeaponType : uint8
{
    Pistol UMETA(DisplayName = "Pistol"),
    Shotgun UMETA(DisplayName = "Shotgun"),
    RocketLauncher UMETA(DisplayName = "Rocket Launcher")
};

EWeaponType是该枚举类型的名称,PistolShotgunRocketLauncher是具体的枚举值。

UENUM

UENUM将枚举类型进行标记,方便UHT为其生成相应的类型文件,生成反射系统需要的代码。BlueprintType说明符令该枚举可以在蓝图中自如使用。

UMETA

使用UMETA宏来指定每个枚举值指定一个显示名,即在蓝图使用中和UI中显示的名称。

TEnumAsByte

虚幻引擎还提供了一种特殊类型的枚举,称为TEnumAsByte,用于加强类型安全并且解决一些常见的错误,主要是一些将枚举类型强行用作其基础类型的应用场合,例如意外使用枚举作为数组的索引。

TEnumAsByte<EWeaponType> Weapon = EWeaponType::Shotgun;

这里就声明了一个TEnumAsByte<EWeaponType>类型的枚举变量Weapon,它本身其实是一个结构体,其中只有一个简单的uint8类型的字段。这是一种典型的面向对象的做法,用一个类型对象将数据封装,这样,当你用一个枚举值去为另一个枚举值赋值的时候就会报错了,这种做法进一步保证了类型安全。

在将枚举类型变量公布给蓝图使用时,通常需要将它与基本枚举类型结合起来进行类型的声明。

总结

枚举类型是一种强大的编程工具,可以使你的代码更加清晰、简洁、易于维护。在使用时,要注意选择适当的技巧,以确保你的代码能够正常工作并避免潜在的错误。

希望文中的例子可以帮助更多人更好地了解如何在编写代码时使用枚举类型。文章来源地址https://www.toymoban.com/news/detail-433039.html

到了这里,关于虚幻C++中的细节之枚举类型(enum)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 自定义类型之枚举类型(enum)和联合体类型(union)

    目录   枚举类型(enum) 什么是枚举类型? 枚举类型的使用 枚举类型的优势 枚举类型的应用场景 总结 联合体类型(union) 什么是联合体? 联合体的应用场景 联合体的注意事项 总结 枚举类型是C语言中一种非常有用的数据类型,它允许程序员定义一组命名的常量。枚举类型

    2024年02月20日
    浏览(36)
  • C++枚举解读(enum)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 对于开发C++来说,枚举是一个几乎必然用到的功能。当然今天要讲的枚举肯定不是平常漫不经心的使用,而是从里到外地深扒它,逐渐揭开它神秘地面纱,发现一些未曾注意到地东西。 枚举(enumeration)类

    2024年02月13日
    浏览(36)
  • 【C++】枚举enum使用详解

    目录 一.什么是枚举enum(WHAT) 二.使用枚举enum的场景(WHEN and WHERE) 三.如何使用枚举enum(HOW) 1)枚举的定义 2)枚举的初始化 3)指定枚举类型  4)声明枚举对象 5)枚举对象赋值问题 6)枚举的取值范围 四.枚举enum的应用 枚举(enumeration)和类相似,能够定义一种新的数据类型,不同的

    2024年02月15日
    浏览(31)
  • Rust 数据类型 之 类C枚举 c-like enum

    目录 枚举类型 enum 定义和声明 例1:Color 枚举 例2:Direction 枚举 例3:Weekday 枚举 类C枚举 C-like 打印输出 强制转成整数 例1:Weekday 枚举 例2:HttpStatus 枚举 例3:Color 枚举 模式匹配 match 表达式 枚举方法 枚举类型是一种用于表示一组有限数量相互关联的离散型数据,这些值可

    2024年02月16日
    浏览(31)
  • UE 虚幻引擎 C++ 线程锁,作用域锁

    UE 里面的线程锁比较常用的就是 FCriticalSection + FScopeLock。 FCriticalSection 是锁对象。 FScopeLock 是锁的作用域对象。 1. 定义锁对象 定义一个 FCriticalSection 锁对象,这个对象可以是全局的,也可以是类变量,这个根据实际情况使用。唯一需要保证的就是,需要同步的代码都需要

    2024年02月14日
    浏览(22)
  • TS—枚举Enum用法

    枚举用于定义数据集合,使用枚举可以定义一些带名字的常量,有普通枚举、字符串枚举和常量枚举等类型。 普通枚举:初始值默认为 0,其余的属性按顺序依次递增。 也可手动设置初始值(其余的属性依旧按顺序递增): 字符串枚举: 常量枚举:使用 const 修饰的枚举

    2024年02月16日
    浏览(28)
  • TypeScript【enum 枚举】

    导语 在 TypeScript 中,新增了很多具有特性的一些数据类型处理方法, enum 【枚举】 就是其中,很具有代表性的一种,所以本章节就来聊聊 在 TypeScript 中如何去运用 enum 【枚举】 。 枚举的 概念 : 枚举(Enum)类型 用于取值被限定在一定范围内的场景 ,比如一周只能有七天

    2024年02月14日
    浏览(28)
  • ffmpeg enum AVChannel枚举解析

    AVChannel枚举是在2022-12-20的提交中添加的,对应的版本号是5.1. 这个提交的描述是\\\"avutil/channel_layout: add AVChannel enum and related functions\\\"。 AVChannel 是一个枚举类型,用于表示音频数据的各个声道。在音频数据中,一个“声道”是一个独立的音频信号,它可以被独立处理和播放。例如

    2024年02月11日
    浏览(25)
  • C语言中enum(枚举)详解

    enum 是 enumerate(列举,枚举)一词的缩写,是 C 语言中的一种 常量 ,被称为 enumeration constant 。 enum 提供了一种很方便的方法来将值和名称关联起来,是 #define 的一种替代方法。 enum 可以看作是一种特殊的数组,是 常量组成的列表 ,而且这个常量只能是整数型。 所以如果是

    2024年02月13日
    浏览(26)
  • 【虚幻引擎】UE5 C++编译和打包失败的原因

    解决办法一:可以去官网下载https://dotnet.microsoft.com/en-us/download/dotnet/3.1   解决方案二:打开Visual Studio Installer,选择单个组件,勾选NET Core 3.1 原因:这是由于更新版本到5.03的时候, 产生的 解决办法一:使用低版本 解决办法二:使用低版本的TP_VirtualRealityBP.upack,替换这个报

    2024年02月03日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包