UE_C++ —— UE反射系统(二)

UE5 C++(十四)— Interface的使用 接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。接口类中不可以声明成员变量,静态变量。可以声明静态常量作为接口的返回值状态,需要在对应的cpp中定义并初始化,访问时需要使用"接口类型::静态常量名"访问定义的接口方法使用virtual 修饰符 和 “=0” 修饰,表示该方法是纯虚的。因为接口类是无法创建对象的,所以不应该编写构造函数和析构函数。 阅读详情

目录

一,Properties

二,UFunctions

三,Metadata Specifiers

四,Unreal Smart Pointer Library


一,Properties

        Properties 属性使用标准的C++变量语法声明,前面用 UPROPERTY 宏来定义属性变量的说明符和元数据;

UPROPERTY([specifier, specifier, ...], [meta(key = value, key = value, ...)])
Type VariableName;

核心数据类型

// Integers
uint8、uint16、uint32、uint64
int8、int16、int32、int64
As Bitmasks // 元标记可使整数作为下拉列表形式可供编辑;
/*~ BasicBits appears as a list of generic flags in the editor, instead of an integer field. */
UPROPERTY(EditAnywhere, Meta = (Bitmask))
int32 BasicBits;
/*~ You can set MyFunction using a generic list of flags instead of typing in an integer value. */
UFUNCTION(BlueprintCallable)
void MyFunction(UPARAM(meta = (Bitmask)) int32 BasicBitsParam)
//自定义bitflags名称
UENUM(Meta = (Bitflags))
enum class EColorBits
{
	ECB_Red,
	ECB_Green,
	ECB_Blue
};
//将定义好的枚举转化为bitmask
UENUM(Meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class EColorBits
{
	ECB_Red  = 0x01,
	ECB_Green = 0x02,
	ECB_Blue  = 0x04
};

ENUM_CLASS_FLAGS(EColorBits);

//定义好后引用
/*~ This property lists flags matching the names of values from EColorBits. */
UPROPERTY(EditAnywhere, Meta = (Bitmask, BitmaskEnum = "EColorBits"))
int32 ColorFlags;

/*~ MyOtherFunction shows flags named after the values from EColorBits. */
UFUNCTION(BlueprintCallable)
void MyOtherFunction(UPARAM(meta = (Bitmask, BitmaskEnum = "EColorBits")) int32 ColorFlagsParam)

 

// Floating Point Types
float,double
// Boolean Types 可使用C++ bool关键字或位域
uint32 bIsHungry : 1;
bool bIsThirsty;
// Strings 支持三种核心类型的字符串
    // FString 是典型的"动态字符数组"字符串类型;
    // FName 是对全局字符串表中不可变且不区分大小写的字符串的引用;相较于FString,大小更小,更能高效的传递,但更难以操控;
    // FText 是指定用于处理本地化的更可靠的字符串表示;
// 大多数情况下,使用TCHAR类型来表示字符,TEXT()宏可用于表示TCHAR文字;
MyDogPtr->DogName = FName(TEXT("Samson Aloysius"));

Property Specifiers

AdvancedDisplay属性将被放置在高级选项下;
AssetRegistrySearchable此属性及其值都将自动添加到资产注册表中;
BlueprintAssignable仅适用于多播代理,公开要在蓝图中分配的属性;
BlueprintAuthorityOnly必须是多播代理,在蓝图中,只接受标记为BlueprintAuthorityOnly的事件;
BlueprintCallable仅限多播代理,应公开属性以在Blueprint代码中调用;
BlueprintGetter=GetterFunctionName指定自定义访问器函数,如也没有标记BlueprintSetter或BlueprintReadWrite,则隐式地为BlueprintReadOnly;
BlueprintSetter=SetterFunctionName具有自定义赋值函数,并隐式标记为BlueprintReadWrite;注意,mutator函数必须命名并属于同一类;
BlueprintReadOnly蓝图只读此属性,与BlueprintReadWrite规范不兼容;
BlueprintReadWrite蓝图可读写此属性,与BlueprintReadOnly规范不兼容;
Category="TopCategory\|SubCategory\|..."指定在蓝图中显示属性类别,使用|运算符定义嵌套类别;
DuplicateTransient在任何类型的复制(复制/粘贴、二进制复制等)过程中,属性的值都应重置为类默认值;
EditAnywhere可通过原型和实例上的属性窗口进行编辑,与"Visible"说明符不兼容;
VisibleAnywhere在所有属性窗口中可见,但无法编辑;与“Edit”规范不兼容;
EditDefaultsOnly只可通过原型的属性窗口进行编辑,与"Visible"说明符不兼容;
EditInstanceOnly只可通过实例上的属性窗口进行编辑,与"Visible"说明符不兼容;
EditFixedSize仅适用于动态数组,将防止用户通过虚幻编辑器属性窗口更改数组的长度;
EditInline允许在属性检查器中编辑此属性引用的对象的属性(仅适用于对象引用,包括对象引用数组);
Export仅适用于对象属性(或对象数组)。指示在复制对象时(例如用于复制/粘贴操作),分配给此属性的对象应作为子对象块整体导出,而不是仅输出对象引用本身;
Config属性将可配置;当前值可以保存到与类关联的.ini文件中,并在创建时加载;在默认属性中不能给值;隐式BlueprintReadOnly;
GlobalConfig与Config相似,只是不能在子类中重写它;在默认属性中不能给值;隐式BlueprintReadOnly;
Instanced仅限于对象(UCLASS)属性;当创建此类的实例时,将获得默认情况下分配给此属性的Object的唯一副本;用于实例化类默认属性中定义的子对象;隐式EditInline、Export;
Interp该值可由序列器中的轨迹随时间驱动;
Localized定义一个本地化值,主要用于字符串,隐式ReadOnly;
NativeC++代码负责对其进行序列化并暴露给垃圾回收;
NoClear防止编辑器将此对象引用设置为无,隐藏编辑器中的清除(和浏览)按钮;
NoExport仅对native类有用,不应包含在自动生成的类声明中;
NonPIEDuplicateTransient在复制过程中,将重置为默认值,除非是PIE;
NonTransactional对此属性值的更改不会包含在编辑器的撤消/重做历史记录中;
NotReplicated跳过复制,仅适用于服务请求函数中的结构体成员和参数;
Replicated该属性应通过网络进行复制;
ReplicatedUsing=FunctionName指定了一个回调函数,当属性通过网络更新时执行该函数;
RepRetry仅对结构体属性有用;如此属性未能完全发送(如,对象引用尚无法通过网络序列化),请重试复制;对于简单的引用,这是默认值,但对于结构体,由于带宽成本,这通常是不可取的,因此除非指定此标志,否则它将被禁用;
SaveGame一种在属性级别显式包含检查点/保存系统字段的简单方法;该标志应设置在所有旨在成为已保存游戏一部分的字段上,然后可以使用代理存档器对其进行读/写;
SerializeTextnative属性应序列化为文本(ImportText、ExportText);
SkipSerialization此属性不会被序列化,但仍然可以导出为文本格式(如用于复制/粘贴操作);
SimpleDisplay可见或可编辑的属性显示在“Details”面板中,无需打开“Advanced”部分即可查看;
TextExportTransient此属性不会导出为文本格式(因此不能用于复制/粘贴操作);
Transient属性是瞬态的,意味着不会被保存或加载;以这种方式标记的属性将在加载时填充为零;
VisibleDefaultsOnly此属性仅在原型的属性窗口中可见,不能编辑;与任何“Edit”都不兼容;
VisibleInstanceOnly此属性仅在实例的属性窗口中可见,对原型不可见,且不可编辑;与任何“Edit”都不兼容;

Metadata Specifiers

        声明类、接口、结构体、枚举、枚举值、函数,或属性时,可添加 元数据说明符 来控制其与引擎和编辑器各方面的相处方式;每一种类型的数据结构或成员都有自己的元数据说明符列表;

注,Metadata只存在于编辑器中,不要编写能够访问到Metadata的游戏逻辑;

AllowAbstract="true/false"用于Subclass和SoftClass属性,说明抽象类属性是否应显示在类选取器中;
AllowedClasses="Class1, Class2, .."用于FSoftObjectPath属性,逗号分隔的列表,表明要显示在资源选取器中的资源类类型;
AllowPreserveRatio用于Fvector属性;在细节面板中显示此属性时将添加一个比率锁;
ArrayClamp="ArrayProperty"用于整数属性,将可在UI中输入的有效值锁定在0和命名数组属性的长度之间;
AssetBundles用于SoftObjectPtr或SoftObjectPath属性,主数据资源中使用的束列表命名,指定此引用属于哪个束的一部分;
BlueprintBaseOnly用于Subclass和SoftClass属性,说明蓝图类是否应显示在类选取器中;
BlueprintCompilerGeneratedDefaults属性默认项由蓝图编译器生成,CopyPropertiesForUnrelatedObjects在编译后调用时将不会被复制;
ClampMin="N"用于浮点和整数属性,指定可在属性中输入的最小值N;
ClampMax="N"用于浮点和整数属性。指定可在属性中输入的最大值N;
ConfigHierarchyEditable此属性被序列化为一个配置(.ini)文件,可在配置层级中的任意处进行设置;
ContentDir由FDirectoryPath属性使用,说明将使用Content文件夹中的Slate风格目录选取器来选取路径;
DisplayAfter="PropertyName"在蓝图编辑器中,名为PropertyName的属性后即刻显示此属性;前提是两个属性属于同一类别,则忽略其在源代码中的顺序进行显示;如多个属性有相同的DisplayAfter值和相同的DisplayPriority值,将在指定属性之后,按照自身在标头文件中声明的顺序显示;
DisplayName="Property Name"此属性显示的命名,不显示代码生成的命名;
DisplayPriority="N"如两个属性有相同的DisplayAfter值,或属于同一类别且无DisplayAfter元标签,则此属性将决定其顺序;最高优先级值为1,表示DisplayPriority值为1的属性将在DisplayProirity值为2的属性之上显示;如多个属性有相同的DisplayAfter值,其将按照在标头文件中声明的顺序显示;
DisplayThumbnail="true"说明属性是一个资源类型,其应显示选中资源的缩略图;
EditCondition="BooleanPropertyName"对一个布尔属性进行命名,此属性用于说明此属性的编辑是否被禁用;将"!"放置在属性命名前可颠倒测试;
EditFixedOrder使排列的元素无法通过拖拽来重新排序;
ExactClass="true"结合AllowedClasses用于FSoftObjectPath属性;说明是否只能使用AllowedClasses中指定的准确类,或子类是否同样有效;
ExposeFunctionCategories="Category1, Category2, .."在蓝图编辑器中编译一个函数列表时,指定其函数应被公开的类目的列表;
ExposeOnSpawn="true"指定此属性是否应在此类类型的一个Spawn Actor节点上公开;
FilePathFilter="FileType"由FFilePath属性使用;说明在文件选取器中显示的路径过滤器;常规值包括"uasset"和"umap",但这些并非唯一可能的值;
GetByRef使该属性的"Get"蓝图节点返回对属性的常量引用,而不是其值的副本;只对稀疏类数据生效,只能在不存在NoGetter时使用;
HideAlphaChannel用于Fcolor和FLinearColor属性;说明详细显示属性控件时Alpha属性应为隐藏状态;
HideViewOptions用于Subclass和SoftClass属性;隐藏在类选取器中修改显示选项的功能;
InlineEditConditionToggle表示出布尔属性只内联显示为其他属性中的一个编辑条件切换,不应显示在其自身的行上;
LongPackageName由FDirectoryPath属性使用;将路径转换为一个长的包命名;
MakeEditWidget用于变换或旋转体属性,或变换/旋转体的排列;说明属性应在视口中公开为一个可移动控件;
NoGetter防止蓝图为该属性生成一个"get"节点,只对稀疏类数据生效;
ScriptName="DisplayName"在将此类、属性或函数导出到脚本语言时使用的名称;可以包含以启用的名称作为以分号分隔的额外条目;

二,UFunctions

        UFunction是UE反射系统可识别的C++函数,UObject或蓝图函数库都可将成员函数声明为UFunction,通过在头文件中将 UFunction 宏放置在函数声明上方;宏将支持 函数说明符 来更改虚幻引擎解译和使用函数的方式;

UFUNCTION([specifier1=setting1, specifier2, ...], [meta(key1="value1", key2, ...)])
ReturnType FunctionName([Parameter1, Parameter2, ..., ParameterN1=DefaultValueN1, ParameterN2=DefaultValueN2]) [const];

        通过函数说明符将UFunctions公共给蓝图可视化脚本(Blueprint Visual Scripting)图表,以便开发者从蓝图调用或扩展UFunction,而无需更改C++代码;

        在类的默认属性中,UFunctions可绑定到Delegates,以执行一些操作(如将操作与用户输入相关联);还可充当网络回调,意味着当某个变量受网络更新影响时,用户可以将其用于接收通知并运行自定义代码;

        用户甚至可创建自己的控制台命令(通常为 debug、configuration 或 cheat code 命令),并能在开发版本中从游戏控制台调用这些命令,或将拥有自定义功能的按钮添加到关卡编辑器中的游戏对象;

Function Specifiers

        声明函数时,可添加 函数说明符,以控制函数相对于引擎和编辑器的各个方面的行为方式;

BlueprintAuthorityOnly如在具有网络权限的机器上运行(服务器、专用服务器或单人游戏),此函数将仅从蓝图代码执行;
BlueprintCallable函数可在蓝图或关卡蓝图图表内执行;
BlueprintCosmetic此函数为修饰性的,无法在专用服务器上运行;
BlueprintImplementableEvent此函数可在蓝图或关卡蓝图图表内实现;
BlueprintPure

此函数不对拥有它的对象产生任何影响,可在蓝图或关卡蓝图图表中执行;

默认,带有 const 标记的函数将作为纯函数公开,使用BlueprintPure=false可设置为非纯函数;

纯函数不会缓存结果,因此在对蓝图函数进行任何重大操作时都需要小心;比较好的做法是避免在蓝图纯函数中输出数组属性;

CallInEditor可在实例上通过细节面板中调用此函数;
Category = "TopCategory\|SubCategory\|Etc"在蓝图编辑工具中显示指定函数的类别;使用 | 运算符定义嵌套类别;
BlueprintNativeEvent此函数旨在被蓝图覆盖掉,但也具有默认原生实现;用于声明名称与主函数相同的附加函数,但末尾添加了_Implementation,是写入代码的位置;如未找到任何蓝图覆盖,该自动生成的代码将调用 _Implementation 方法;
Client此函数仅在调用此函数对象的客户端上执行;用于声明名称与主函数相同的附加函数,但末尾添加了_Implementation;必要时,此自动生成的代码将调用 _Implementation 方法;
Server此函数仅在服务器上执行;用于声明名称与主函数相同的附加函数,但末尾添加了 _Implementation,是写入代码的位置;必要时,此自动生成的代码将调用 _Implementation 方法;
WithValidation用于声明名称与主函数相同的附加函数,但末尾需要添加_Validate;此函数使用相同的参数,但是会返回bool,以指示是否应继续调用主函数;
CustomThunkUnrealHeaderTool 代码生成器将不为此函数生成thunk,用户需要自己通过 DECLARE_FUNCTION 或 DEFINE_FUNCTION 宏来提供thunk;
Exec此函数可从游戏内控制台执行;仅在特定类中声明时,Exec命令才有效;
NetMulticast此函数将在服务器上本地执行,也将复制到所有客户端上,无论该Actor的 NetOwner 为何;
Reliable此函数将通过网络复制,并且一定会到达,即使出现带宽或网络错误;仅在与Client或Server配合使用时才有效;
Unreliable此函数将通过网络复制,但可能会因带宽限制或网络错误而失败;仅在与Client或Server配合使用时才有效;
SealedEvent无法在子类中覆盖此函数;SealedEvent关键词只能用于事件;对于非事件函数,请声明为static或final,以密封它们;
ServiceRequest此函数为RPC(远程过程调用)服务请求,这意味着 NetMulticast 和 Reliable;
ServiceResponse此函数为RPC服务响应,这意味着 NetMulticast 和 Reliable;

Metadata Specifiers

        声明类、接口、结构体、枚举、枚举值、函数,或属性时,可添加 元数据说明符 来控制其与引擎和编辑器各方面的相处方式;每一种类型的数据结构或成员都有自己的元数据说明符列表;

注,Metadata只存在于编辑器中,不要编写能够访问到Metadata的游戏逻辑;

AdvancedDisplay="Parameter1, Parameter2, .."以逗号分隔的参数列表将显示为高级引脚(需UI扩展);
AdvancedDisplay=N用一个数字替代 N ,第N之后的所有参数将显示为高级引脚(需UI扩展);如:'AdvancedDisplay=2' 将把前两个之外的所有参数标记为高级;
ArrayParm="Parameter1, Parameter2, .."说明 BlueprintCallable 函数应使用一个Call Array Function节点,且列出的参数应被视为通配符数组属性;
ArrayTypeDependentParams="Parameter"使用 ArrayParm 时,此说明符将指定一个参数,其将确定 ArrayParm 列表中所有参数的类型;
AutoCreateRefTerm="Parameter1, Parameter2, .."如列出参数(由引用传递)的引脚未连接,其将拥有一个自动创建的默认项;这是蓝图的一个便利功能,经常在数组引脚上使用;
BlueprintAutocast仅能由来自蓝图函数库的静态 BlueprintPure 函数使用;Cast节点将根据返回类型和函数首个参数的类型来自动添加;
BlueprintInternalUseOnly此函数是一个内部实现细节,用于实现另一个函数或节点;其不会直接在蓝图图表中公开;
BlueprintProtected此函数只能在蓝图中的拥有对象上调用;其无法在另一个实例上调用;
CallableWithoutWorldContext用于拥有一个 WorldContext 引脚的 BlueprintCallable 函数,说明函数可被调用,即使其类不实现 GetWorld 函数也同样如此;
CommutativeAssociativeBinaryOperator说明 BlueprintCallable 函数应使用Commutative Associative Binary节点,此节点缺少引脚命名,但拥有一个创建额外输入引脚的 添加引脚(Add Pin) 按钮;
CompactNodeTitle="Name"说明 BlueprintCallable 函数应在压缩显示模式中显示,并提供在该模式中显示的命名;
CustomStructureParam="Parameter1, Parameter2, .."列出的参数都会被视为通配符;
DefaultToSelf用于 BlueprintCallable 函数,说明对象属性的命名默认值应为节点的自我情境;
HideSelfPin隐藏用于指出函数调用所处对象的self引脚;self引脚在与调用蓝图的类兼容的 BlueprintPure 函数上为自动隐藏状态;这通常与 DefaultToSelf 说明符共用;
DeprecatedFunction蓝图对此函数进行引用时将引起编译警告,告知用户函数已废弃;可使用 DeprecationMessage 元数据说明符添加到废弃警告消息(如提供说明如何替代已废弃的函数);
DeprecationMessage="Message Text"如果函数已废弃,尝试编译使用此函数的蓝图时,其将被添加到标准废弃警告;
DeterminesOutputType="Parameter"函数的返回类型将根据连接到命名参数引脚的输入动态更改;该参数应该是一个模板类型,比如 TSubClassOf<X> 或 TSoftObjectPtr<X>,其中函数的原始返回类型是 X* 或带有 X* 作为值类型的容器,比如 TArray<X*>;
DevelopmentOnly被标记为 DevelopmentOnly 的函数只会在Development模式中运行。这适用于调试输出之类的功能(但其不应存在于发布产品中);
DisplayName="Blueprint Node Name"此节点在蓝图中的命名将被此处提供的值所取代,而非代码生成的命名;
ExpandEnumAsExecs="Parameter"用于 BlueprintCallable 函数,说明应为参数使用的枚举中的每个条目创建一个输入执行引脚;命名参数必须是引擎通过 UENUM 标签识别的一个列举类型;
ForceAsFunction将没有来自事件的返回值的 BlueprintImplementableEvent 更改为函数;
HidePin="Parameter"用于 BlueprintCallable 函数,说明参数引脚应从用户视图中隐藏;注:使用此方式每个函数只能隐藏一个参数引脚;
InternalUseParam="Parameter"与 HidePin 相似,这将在用户视图中隐藏命名参数的引脚,只能用于一个函数的一个参数;
KeyWords="Set Of Keywords"指定在搜索此函数时可使用的一套关键词,如合适放置节点在蓝图图表中调用函数;
Latent说明一个延迟操作,延迟操作拥有类型为 FLatentActionInfo 的一个参数,此参数由 LatentInfo 说明符命名;
LatentInfo="Parameter"用于延迟 BlueprintCallable 函数,说明哪个参数是LatentInfo参数;
MaterialParameterCollectionFunction用于 BlueprintCallable 函数,说明应使用材质覆盖节点;
NativeBreakFunc用于 BlueprintCallable 函数,说明函数应以标准Break Struct节点的方式进行显示;
NotBlueprintThreadSafe只在蓝图函数库中有效,此函数将被视为拥有类的整体 BlueprintThreadSafe 元数据的一个例外;
ShortToolTip="Short tooltip"完整提示文本过长时使用的简短提示文本,如父类选取器对话;
ToolTip="Hand-written tooltip覆盖从代码注释自动生成的提示文本;
UnsafeDuringActorConstruction在Actor构造时调用此函数并非安全操作;
WorldContext="Parameter"由 BlueprintCallable 函数使用,说明哪个参数决定运算正在发生的World;
ScriptName="DisplayName"在将此类、属性或函数导出到脚本语言时使用的名称;可以包含以启用的名称作为以分号分隔的额外条目;

Function Parameter Specifiers

Out声明由引用传递的参数,使函数对其进行修改;
Optional通过任选关键词可使部分函数参数变为任选,便于调用,任选参数的数值(调用方未指定)取决于函数;

Delegates

        委托可以以泛型、类型安全的方式调用C++对象上的成员函数;委托可以动态绑定到任意对象的成员函数,在将来调用该对象的函数,即使调用者不知道该对象的类型;

Timers

        定时器 可用于在一段延迟后执行某个动作,或在一段时间内执行动作;如,可以让玩家在获得某个物品后保持无敌10秒,并在10秒后失去无敌效果,或让玩家在进入毒气场景后每秒受到伤害;这类效果都可以通过定时器实现;

三,Metadata Specifiers

         声明UClasses、UFunctions、UProperties、UEnums和UInterfaces时使用的元数据关键词,表示其与引擎和关卡编辑器诸多方面的互动方式;

        当声明classe、interfaces、structs、enums、enum values、functions、or propertie时,可添加 Metadata Specifiers 以控制其与引擎和编辑器各方面的交互方式;每一种类型的数据结构或成员都有自己的元数据说明符列表;

注,Metadata仅存在于编辑器中,不要编写能够访问到Metadata的游戏逻辑;

        使用单词 meta,后接说明符列表,来添加元数据说明符;可以将它们的值添加到 UCLASS、UENUM、UINTERFACE、USTRUCT、UFUNCTION 或 UPROPERTY 宏;

{UCLASS/UENUM/UINTERFACE/USTRUCT/UFUNCTION/UPROPERTY}(SpecifierX, meta=(MetaTag1="Value1", MetaTag2, ..), SpecifierY)

        添加Metadata Specifiers到枚举类型内的特定值,可将 UMETA 标签添加到值本身;

UENUM()
enum class EMyEnum : uint8
{
	// DefaultValue Tooltip
	DefaultValue = 0 UMETA(MetaTag1="Value1", MetaTag2, ..),

	// ValueWithoutMetaSpecifiers Tooltip
	ValueWithoutMetaSpecifiers,

	// ValueWithMetaSpecifiers Tooltip
	ValueWithMetaSpecifiers UMETA((MetaTag1="Value1", MetaTag2, ..),

	// FinalValue Tooltip
	FinalValue (MetaTag1="Value1", MetaTag2, ..)
};

四,Unreal Smart Pointer Library

        虚幻智能指针库 为C++11智能指针的自定义实现,旨在减轻内存分配和追踪的负担;该实现包括行业标准 共享指针(Shared Pointers)、弱指针(Weak Pointers) 和 唯一指针(Unique Pointers);其还可添加 共享引用(Shared References),此类引用的行为与不可为空的共享指针相同;虚幻Objects使用更适合游戏代码的单独内存追踪系统,因此这些类无法与 UObject 系统同时使用;

Smart Pointer Types

        智能指针可影响其包含或引用对象的寿命,不同智能指针对对象有不同的限制和影响;

Shared Pointers

(TSharedPtr)

共享指针拥有其引用的对象,无限防止该对象被删除,并在无共享指针或共享引用(见下文)引用其时,最终处理其的删除;

共享指针可为空,意味其不引用任何对象;任何非空共享指针都可对其引用的对象生成共享引用;

Shared References

(TSharedRef)

共享引用的行为与共享指针类似,即其拥有引用的对象;对于空对象而言,其存在不同;共享引用须总是引用非空对象;共享指针无此类限制,因此共享引用可转换为共享指针,且该共享指针引用有效对象;要确认引用的对象是非空,或者要表明共享对象所有权时,请使用共享引用;

Weak Pointers

(TWeakPtr)

弱指针类与共享指针类似,但不拥有其引用的对象,因此不影响其生命周期;此属性中断引用循环,因此十分有用,但也意味弱指针可在无预警的情况下随时变为空;因此,弱指针可生成指向其引用对象的共享指针,确保程序员能对该对象进行安全临时访问;

Unique Pointers 

(TUniquePtr)

唯一指针仅会显式拥有其引用的对象;仅有一个唯一指针指向给定资源,因此唯一指针可转移所有权,但无法共享;复制唯一指针的任何尝试都将导致编译错误;唯一指针超出范围时,其将自动删除其所引用的对象;

注,对唯一指针引用的对象进行共享指针或共享引用的操作十分危险;即使其他智能指针继续引用该对象,此操作不会取消唯一指针自身被销毁时删除该对象的行为;同样,不应为共享指针或共享引用引用的对象创建唯一指针;

Benefits of Smart Pointers

防止内存泄漏共享引用不存在时,智能指针(弱指针除外)会自动删除对象;
弱引用弱指针会中断引用循环并阻止悬挂指针;
可选择的线程安全能指针库包括线程安全代码,可跨线程管理引用计数;如无需线程安全,可用其换取更好性能;
运行时安全共享引用从不为空,可随时取消引用;
传达意图可轻松区分对象所有者和观察者;
内存智能指针在64位下仅为C++指针大小的两倍(加上共享的16字节引用控制器);唯一指针除外,其与C++指针大小相同;

Helper Classes and Functions

        虚幻智能指针库提供多个助手类和函数,以便使用智能指针时更加容易、直观;

Classes
TSharedFromThis从TSharedFromThis派生类,添加AsShared or SharedThis函数;此类函数可获取对象的 TSharedRef;
Functions
MakeShared、MakeShareable

在常规C++指针中创建共享指针;

MakeShared 会在单个内存块中分配新的对象实例和引用控制器,但要求对象提交public构造函数;

MakeShareable 的效率较低,但即使对象的构造函数为私有,其仍可运行;利用此操作可拥有非自己创建的对象,并在删除对象时支持自定义行为;

StaticCastSharedRef、StaticCastSharedPtr静态投射效用函数,通常用于向下投射到派生类型;
ConstCastSharedRef、ConstCastSharedPtr将 const 智能引用或智能指针分别转换为 mutable 智能引用或智能指针;

智能指针实现细节

        在功能和效率方面,虚幻智能指针库中的智能指针具有一些共同特征;

Speed

        要使用智能指针时,始终考虑性能;智能指针非常适合某些高级系统、资源管理或工具编程;但部分智能指针类型比原始C++指针更慢,这种开销使得其在低级引擎代码(如渲染)中用处不大;

智能指针的部分性能优势包括:

  • 所有运算均为常量时间;
  • 取消引用多数智能指针的速度和原始C++指针的相同(在发布版本中);
  • 复制智能指针不会分配内存;
  • 线程安全智能指针是无锁的;

智能指针的性能缺陷包括:

  • 创建和复制智能指针比创建和复制原始C++指针需要更多开销;
  • 保持引用计数增加基本运算的周期;
  • 部分智能指针占用的内存比原始的C++更多;
  • 引用控制器有两个堆分配;使用 MakeShared 代替 MakeShareable 可避免二次分配,并可提高性能;

Intrusive Accessors

        共享指针是non-intrusive,意味对象不知道其是否为智能指针拥有;此通常是可以接受的,但在某些情况下,可能要将对象作为共享引用或共享指针进行访问;为此,使用对象的类作为模板参数,从 TSharedFromThis 派生对象的类;TSharedFromThis 提供两个函数:AsShared 和 SharedThis,可将对象转换为共享引用(并从共享引用转换为共享指针);使用固定返回共享引用的类factory时,或需将对象传到需要共享引用或共享指针的系统时,此操作十分有用;AsShared 会将类返回为最初作为模板参数传到 TSharedFromThis 的类型返回,其可能是调用对象的父类型,而 SharedThis 将直接从该类型衍生类型,并返回引用该类型对象的智能指针;

class FRegistryObject;
	class FMyBaseClass: public TSharedFromThis<FMyBaseClass>
	{
		virtual void RegisterAsBaseClass(FRegistryObject* RegistryObject)
		{
			// Access a shared reference to 'this'.
			// We are directly inherited from <TSharedFromThis> , so AsShared() and SharedThis(this) return the same type.
			TSharedRef<FMyBaseClass> ThisAsSharedRef = AsShared();
			// RegistryObject expects a TSharedRef<FMyBaseClass>, or a TSharedPtr<FMyBaseClass>. TSharedRef can implicitly be converted to a TSharedPtr.
			RegistryObject->Register(ThisAsSharedRef);
		}
	};
	class FMyDerivedClass : public FMyBaseClass
	{
		virtual void Register(FRegistryObject* RegistryObject) override
		{
			// We are not directly inherited from TSharedFromThis<>, so AsShared() and SharedThis(this) return different types.
			// AsShared() will return the type originally specified in TSharedFromThis<> - TSharedRef<FMyBaseClass> in this example.
			// SharedThis(this) will return a TSharedRef with the type of 'this' - TSharedRef<FMyDerivedClass> in this example.
			// The SharedThis() function is only available in the same scope as the 'this' pointer.
			TSharedRef<FMyDerivedClass> AsSharedRef = SharedThis(this);
			// RegistryObject will accept a TSharedRef<FMyDerivedClass> because FMyDerivedClass is a type of FMyBaseClass.
			RegistryObject->Register(ThisAsSharedRef);
		}
	};
	class FRegistryObject
	{
		// This function will accept a TSharedRef or TSharedPtr to FMyBaseClass or any of its children.
		void Register(TSharedRef<FMyBaseClass>);
	};

不要在构造函数中调用 AsShared 或 Shared,共享引用此时并未初始化,将导致崩溃或断言;

Casting

        可通过虚幻智能指针库包含的多个支持函数cast共享指针(和共享引用);Up-casting是隐式的,与C++指针相同;可使用 ConstCastSharedPtr 函数进行const cast,使用 StaticCastSharedPtr 进行static cast(通常是downcast到派生类指针);无run-type类型的信息(RTTI),因此不支持动态转换;

// This assumes we validated that the FDragDropOperation is actually an FAssetDragDropOp through other means.
TSharedPtr<FDragDropOperation> Operation = DragDropEvent.GetOperation();
// We can now cast with StaticCastSharedPtr.
TSharedPtr<FAssetDragDropOp> DragDropOp = StaticCastSharedPtr<FAssetDragDropOp>(Operation);

Thread Safety

        通常仅在单线程上访问智能指针的操作才是安全的。如需访问多线程,请使用智能指针类的线程安全版本:

  • TSharedPtr<T, ESPMode::ThreadSafe>

  • TSharedRef<T, ESPMode::ThreadSafe>

  • TWeakPtr<T, ESPMode::ThreadSafe>

  • TSharedFromThis<T, ESPMode::ThreadSafe>

由于原子引用计数,此类线程安全版本比默认版本稍慢,但其行为与常规C++指针一致:

  • 读取和复制固定为线程安全;

  • 写入和重置须同步后才安全;

注,如多线程永不访问指针,可通过避免使用线程安全版本获得更好性能;

提示和限制

  • 避免将数据作为 TSharedRef 或 TSharedPtr 参数传到函数,此操作将因取消引用和引用计数而产生开销;相反,建议将引用对象作为 const & 进行传递;

  • 可将共享指针向前声明为不完整类型;

  • 共享指针与虚幻对象(UObject 及其派生类)不兼容;引擎具有 UObject 管理的单独内存管理系统,两个系统未互相重叠;

虚幻引擎编程反射系统实现 在虚幻引擎中,反射(Reflection)是支撑蓝图系统、序列化、网络同步等核心功能的底层机制。它通过在编译时生成类型元数据(Metadata),使得C++代码在运行时能够动态查询和操作类、属性及方法。提示:以下是本篇文章正文内容,下面案例可供参考通过 UCLASS、USTRUCT、UPROPERTY、UFUNCTION 等宏标记需要反射的类型或成员。这些宏会在编译前被 Unreal Header Tool (UHT) 解析。// 示例:定义一个反射类。 阅读详情

相关推荐

C++开发者快速上手虚幻引擎:核心概念、反射系统与蓝图协作实战

C++作为高性能系统编程语言,在游戏开发中扮演着核心角色,其直接内存管理和编译期优化特性为复杂逻辑提供了坚实基础。现代游戏引擎通过反射系统扩展了C++的能力,允许在运行时动态查询和操作类信息,这一机制是编辑器可视化与脚本化协作的技术基石。在虚幻引擎中,反射系统通过UCLASS、UPROPERTY等宏实现,将C++类暴露给编辑器,使开发者能够高效构建可迭代的游戏逻辑。这种设计模式特别适合需要高性能计算与灵活设计并重的应用场景,如复杂Gameplay系统、物理模拟和AI行为树。本文以C++开发者视角,深入解析虚

weixin_27676369的博客 289

虚幻蓝图BlueprintCallable与BlueprintPure区别

在日常开发中,BlueprintCallable相信都很常用,但是BlueprintPure就不那么常用了,我也是在项目开发时,需要用C++封装单例对象供蓝图调用时,才用到BlueprintPure,下面简单看一下他们区别。注意:Pure函数一般声明成static ,如果不声明成static,使用函数节点时。以上是我们肉眼可见的区别,下面看一下肉眼不可见的区别。Promote to Variable不可用。Promote to Variable可用。

记录日常开发的小问题备忘 3721

C++笔记之反射、Qt中的反射系统、虚幻引擎中的反射系统

反射就是让程序在运行的时候,通过字符串来访问对象的属性或方法,而不是在编译时就写死。比如:我们想通过"name"这个字符串,去获取或设置一个对象的name属性。Q_OBJECTpublic:private:虚幻引擎的反射是指运行时可以通过字符串等方式访问类、属性、函数等元数据,这使得蓝图、序列化、编辑器属性面板和网络同步等高级功能成为可能。反射是指通过字符串等描述在运行时访问对象的属性或方法**C++**没有内置反射,但可以通过映射和函数指针实现简单模拟Qt。

小勇博客 459

【UE】函数UFUNCTION的BlueprintCallable,BlueprintPure,BlueprintImplementableEvent,BlueprintNativeEvent

C++调蓝图函数:BlueprintImplementableEvent,BlueprintNativeEvent。实现:蓝图C++都可,优先调用蓝图override重写函数,没有重写则调用默认C++函数。蓝图调C++函数:BlueprintCallable,BlueprintPure。PS:若想蓝图C++函数都调用。

weixin_43490759的博客 3409

开源TMS系统cortex-tms私有化部署与二次开发实战指南

运输管理系统(TMS)是现代物流数字化的核心组件,它通过将线下零散的物流操作转化为线上标准化、可追溯的数据流,实现订单、调度、跟踪与结算的全流程管理。其技术原理通常基于微服务架构,采用Spring Boot、Vue.js等成熟技术栈构建,确保系统的稳定性和可扩展性。TMS的技术价值在于显著提升物流企业的运营效率、降低成本并增强过程可控性,尤其适用于中小型物流企业实现从手工管理到系统化管理的跨越。在应用场景上,TMS广泛应用于车队管理、订单跟踪和财务结算等环节。本文聚焦于开源TMS项目cortex-tms,深

weixin_42523907的博客 746

海康威视门禁考勤设备数据对接实战:从被动推送到主动拉取

本文深入探讨了海康威视门禁考勤设备数据对接的两种核心方案:HTTP推送与SDK主动拉取。文章对比了两种方式的适用场景、技术实现与优缺点,为开发者提供了从设备配置、代码编写到工程化部署的完整实战指南,帮助读者根据项目规模、网络环境及数据稳定性要求,做出最合适的技术选型。

weixin_29284657的博客 666

ue4 蓝图调用c++函数 BlueprintCallable

1 新建c++类MyActor,新建继承c++类的蓝图类MB_MyActor 2 编写 c++代码 MyActor.h // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Gam...

sun 5980

波束成形(Beamforming)详解

波束成形(Beamforming)是一种智能天线技术,通过调整天线阵列的相位和幅度,使信号在特定方向上增强,同时抑制干扰,提高通信性能。根据实现方式,可分为固定波束成形和自适应波束成形;按计算方式,则包括模拟、数字和混合波束成形。该技术在 5G/6G、毫米波通信、MIMO、车联网、卫星通信 等领域广泛应用。其关键技术包括 相控阵、预编码、波束扫描和波束跟踪。未来,结合 AI、超大规模 MIMO(XL-MIMO)和太赫兹通信,波束成形将在无线通信、智能交通、环境感知等领域发挥核心作用。

斯黄人民的博客 2383

U++6Interface的使用

UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category=Trigger Reaction) bool ReactToTrigger();BlueprintCallable 引用实现接口的对象的C++或蓝图可以调用使用 BlueprintCallable 说明符的函数。 BlueprintImplementableEvent 使用 BlueprintImplementableEvent 的函数不能在C++中被腹杆,但可以任何实现或

qq_56129271的博客 586

STM32--基于STM32F103C8T6的OV7670摄像头显示

使用 STM32F103C8T6 微控制器驱动 OV7670 摄像头模组,并将图像数据显示在屏幕上,是嵌入式系统中常见的图像采集与显示应用。OV7670 是一款 CMOS VGA 图像传感器,具有高灵敏度、低电压等特点,适用于嵌入式应用。而 STM32F103C8T6 是一款常用的 MCU 控制器,具有丰富的管脚资源和较高的工作频率。

duierrorshuobu的博客 2145

告别‘小目标’丢失!手把手复现DNANet红外检测网络(PyTorch版)

本文详细介绍了如何使用PyTorch从零实现DNANet红外小目标检测网络,重点解析了DNIM模块和CSAM注意力机制的设计与实现。通过实战教程,帮助开发者解决红外小目标检测中的特征提取和训练调参难题,适用于军事侦察、安防监控等场景。

weixin_28701593的博客 252

学习虚幻C++开发日志——虚幻引擎反射系统

初识虚幻反射系统

2301_80888963的博客 1217

[SystemC]SystemC中的模块和程序

SystemC 中的层次结构是使用类 sc_module 创建的。sc_module 可以直接使用,也可以使用宏 SC_MODULE “隐藏”。上面的示例 SC_MODULE 创建了一个名为 nand2 的 sc_module 类对象。它的输出纯粹是输入值的函数。因此,模型可以使用最简单的 SystemC 进程,即 SC_METHOD。摘要:本节包含一个完整的简单设计,用于演示 SystemC 中模块和流程的使用。同样,重要的是要注意这不是典型的设计风格 - 但它很好而且易于理解。为什么要看模块和流程?

元直的博客 1867

虚幻引擎(UE4) 反射系统(Reflection)

反射是程序在运行时检查自身的能力。这是非常有用的,并且是虚幻引擎的基础技术,可以为许多系统提供动力,例如编辑器中的详细信息面板,序列化,垃圾收集,网络复制以及Blueprint / C ++通信。但是,C ++本身不支持任何形式的反射,因此Unreal拥有自己的系统来收集,查询和操纵有关C ++类,结构,函数,成员变量和枚举的信息。我们通常将反射称为属性系统,因为反射也是图形术语。 反射系统是可选的。您需要注释任何您希望在反射系统中可见的类型或属性,虚幻解析工具(UHT)会在编译项目时获取该信息。 .

刀客 4038

SAP UI5 OData V4 操作结果访问:从 getObject 到返回值上下文与 $$inheritExpandSelect

SAP UI5 OData V4 操作结果获取指南 摘要:在 SAP UI5 OData V4 模型中,操作结果需通过绑定上下文获取而非直接从 invoke() 返回。本文详解核心要点: 数据获取路径 使用 invoke() 发起请求后,通过 getBoundContext().getObject() 获取结果 特定场景下 invoke() 可能返回返回值上下文(如草稿切换) 关键实践技巧 使用 $$inheritExpandSelect 继承字段选择,避免二次读取 对象页应用中,通过替换绑定上下文实现无缝

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 311

使用MATLAB和Simulink来设计并仿真一个智能家居火灾报警系统

智能家居火灾报警系统旨在通过烟雾传感器、温度传感器等设备监测家庭环境,一旦检测到异常情况(如烟雾或温度骤升),立即触发警报并采取相应措施。在这个教程中,我们将使用MATLAB和Simulink来设计并仿真一个智能家居火灾报警系统,包括数据采集、处理以及响应机制。

amy_mhd的博客 162

UE4反射系统简析(含实例过程分析)

一、UE4中的反射系统 1.简述: 1.1 什么是UE4反射 在UE4里面,你无时无刻都会看到类似UFUNCTION()这样的宏。官方文档告诉你,只要在一个函数的前面加上这个宏,然后在括号里面加上BlueprintCallable就可以在编辑器里面调用了。按照他的指示,我们就能让我们的函数实现各种各样特别的功能,那这个效果就是通过UE4的反射系统来实现的。这看起来确实非常棒,不过同时给UE4

Jerish的博客 2万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

UE中的反射系统

是微软.NET框架的一种机制,能够在程序运行时动态访问其他程序集中的元数据。比如,虚幻引擎是正在运行的程序,开发者编写的类是其他程序集,虚幻引擎可以访问开发者编写的类。虚幻引擎反射系统通过各种封装开发者编写的类。比如,UCLASSUPROPERTYUFUNCTION宏等,当然,开发者仍旧可以编写标准的C++类。对每种类型的数据结构或成员标记相应的宏可使其成为能够被虚幻引擎反射系统识别的UClassUPropertyUFunction等。

vjsopmh 1296

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

虚幻引擎编程中的LUA脚本访问C++原理与实现

现在想了解虚幻引擎中Lua脚本是如何访问C++的API的。首先,我记得虚幻引擎主要用的是C++,但有时候也会用脚本语言比如Lua来编写游戏逻辑,这样设计可能更灵活。不过,虚幻引擎默认的脚本系统好像是Blueprint,而不是Lua。所以可能需要第三方插件来集成Lua。提示:以下是本篇文章正文内容,下面案例可供参考步骤工具/技术示例插件集成修改.Build.cs依赖反射标记UCLASS、UFUNCTION宏类型绑定插件自动转换或手动注册生命周期管理UE垃圾回收、智能指针。

X_Bai01的博客 1413

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

UE4——反射系统

UE4——反射系统 反射是程序在运行时进行自检的一种能力。它非常有用且在虚幻引擎中基础技术,支撑了诸如 编辑器中的细节面板、序列化、垃圾回收、网络复制、以及蓝图与C++交互等功能。然而,C++原生并不支持任意形式的反射,因此 虚幻引擎有它自己的系统用来 利用、查询以及操作关于C++类、结构体、函数 、成员变量以及枚举的信息。我们特意把反射叫做属性系统,因为反射也是一个图形术语。 反射系统是可以选择加入的。你需要给暴露给反射系统的类型或属性添加注解,这样Unreal Header Tool (UHT)就会在编

weixin_43945471的博客 965

[玩转UE4/UE5动画系统>C++篇>C++基础] 之 C++版模板中那些琐碎而又应知应会的语法知识小结(本文献给刚学完谭浩强就来啃UEC++的同学)

本教程采用图文教程+视频教程的多元化形式,我会为不同的知识点选择适当的表达方式。教程内容将同步免费发布于开发游戏的老王(知乎|优快云)的专栏《玩转UE4/UE5动画系统》。教程中使用的资源及工程将以开源项目的形式更新到GitHub:玩转UE4上。 工程文件: 玩转UE4(GitHub) 文章目录前言语法知识#pragma once是干嘛的?UCLASS()是干嘛的?GENERATED_BODY()是干嘛的?UPROPERTY是干嘛的?FORCEINLINE是干嘛的?类型前面的class关键字是干嘛.

开发游戏的老王 2302

虚幻引擎反射系统

提供可以在多个或不同的类中实现函数和额外的游戏行为。你的玩家角色可以与世界中的各种Actor互动。它在分配从特定类型派生出来的类时很有效。例如,你可以把这个变量公开给蓝图,设计者可以为玩家角色指定生成的武器类别。控制类、接口、结构体、列举、函数,或属性与引擎和编辑器各方面的交互方式。宏使UE注意到新的类、函数和变量。为C++11智能指针的自定义实现,旨在减轻内存分配和追踪的负担。使用宏为提供引擎和编辑器各种功,封装你的类。时,可以使用标准的C++类、函数和变量。,此类引用的行为与不可为空的共享指针相同。

weixin_70256040的博客 510

UE5.3 C++ CDO的初步理解

一.UObjectUObject是所有对象的基类,往上还有UObjectBaseUtility。注释:所有虚幻引擎对象的基类。对象的类型由基于 UClass 类来定义。这为创建和使用UObject的对象提供了 函数,并且提供了应在子类中重写的虚函数。为 UObject 提供工具类的函数,不应直接使用此类。为更底层接口提供给UObject,也不能直接使用反射系统直接,一般是收集UObject的信息。是在运行的时候,拿到运行的对象注册的信息。将这个信息写入对象的表,随时可以取到,访问。

m0_64217692的博客 1918

一周入门 UE C++ 开发教程

用UE虚幻引擎开发项目的时候,可以采用蓝图和C++两种方法,蓝图快捷方便,C++学习成本高。几乎所有的功能都可以用蓝图来实现(蓝图背后其实也是C++,只不过是封装成了蓝图节点),如果要实现复杂、大型功能,蓝图可能就不是很方便,简单项目用蓝图,复杂大型项目用蓝图和C++。所以,不管什么项目,蓝图肯定会用到,普通项目、普通开发者能用蓝图就别用C++。但是在实际开发中难免会遇到UE自带的蓝图功能不满足需求、或者某些功能用蓝图实现起来需要非常多的节点,此时就可以考虑用C++来实现。

毛阿姨的博客 3212

unreal 虚幻引擎学习资料

一 入门资料 1 最重要的学习途径,官方文档,这个一定要看 :unreal 官方文档中文版 2 游戏蛮牛相关资料的整理 :游戏蛮牛 - 手册 - 虚幻引擎4 | UnrealEngine4 二 深入了解虚幻底层原理 1 因为c++自身是没有垃圾回收的,所有虚幻4自己实现了一套垃圾回收机制 :虚幻4垃圾回收剖析 2 同样c++自身也没有类似于java,go等语言的反射系统...

D_Guco的专栏 2938

【UE4】C++编程笔记(一)

【UE4】C++编程简介UPROPERTY()宏如何使用属性说明符UFUNCTION()宏如何使用属性说明符Gameplay类UObjectAActorUActorComponentUStruct引擎工作方式虚幻反射系统说明符传送门对象/Actor迭代器内存管理和垃圾回收UObject和垃圾回收Actor和垃圾回收UStructs非对象引用类命名前缀数字类型字符串FStringFTextFName...

胡嘿嘿 3385
上一篇: UE_C++ —— TSubclassOf
下一篇: UE_C++ —— Metadata Specifiers
挨代码
博客等级 码龄5年 1696粉丝 384原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值