0

0

如何在Unreal Engine 5中使用现代c++特性? (UE C++最佳实践)

冰火之心

冰火之心

发布时间:2026-01-12 16:04:03

|

646人浏览过

|

来源于php中文网

原创

UE5默认C++17,禁用std::unique_ptr管理UObject因GC冲突;C++20仅限非UCLASS模块;范围for需用const引用避免拷贝;蓝图函数参数须用TArray/TMap而非span/View。

如何在unreal engine 5中使用现代c++特性? (ue c++最佳实践)

Unreal Engine 5 默认使用 C++17(UE 5.3 及以后可选 C++20),但引擎自身大量封装了标准库、禁用部分语言特性,并强制使用其内存/对象生命周期管理机制。直接套用现代 C++ 惯例(如 std::shared_ptrauto 推导过度、RAII 构造函数抛异常)极易引发崩溃或资源泄漏。

为什么不能直接用 std::unique_ptr 管理 UObject 子类?

UE 的垃圾回收(GC)系统依赖 UObject 的反射信息和根引用链,而 std::unique_ptr 是纯/堆语义,不参与 GC 注册。一旦你用它持有 UCLASS 实例,GC 会认为该对象不可达并销毁它,而 std::unique_ptr 还在试图管理已释放内存 —— 下次访问必崩。

正确做法是用 UE 原生指针类型:

  • TObjectPtr(推荐,UE 5.2+ 引入,类型安全、支持 GC、可序列化)
  • UActorComponent*(需手动确保生命周期,例如在 BeginDestroy() 中置空)
  • 避免 UActorComponent** 或裸 void* 转换

如何安全启用 C++20 并避开 UE 编译器陷阱?

UE 5.3+ 支持 C++20,但仅限非 UCLASS / USTRUCT 的普通模块(如 Runtime/Core 或自建工具模块)。在 Build.cs 中设置需谨慎:

立即学习C++免费学习笔记(深入)”;

public override void SetupBinaries(
    target,
    ref List OutBinaries
)
{
    base.SetupBinaries(target, ref OutBinaries);
    // 仅对非UObject模块启用C++20
    if (Target.Type != TargetType.Editor && !IsInUObjectModule())
    {
        CppSettings.LanguageStandard = CppLanguageStandard.Cpp20;
    }
}

关键限制:

  • conceptsrangesmodules 在当前 UE 构建系统中仍不被支持(会触发 Unknown type name 'concept'
  • std::format 不可用(MSVC 2019 工具链未完全实现,且 UE 自带 FString::Printf 替代)
  • 所有 UCLASS 头文件必须保持 C++17 兼容(否则反射生成器 UnrealHeaderTool 解析失败)

auto 和范围 for 在容器遍历时要注意什么?

UE 容器(TArrayTMapTSet)重载了 begin()/end(),支持范围 for,但推导类型容易出错:

PaperAiBye
PaperAiBye

支持近30多种语言降ai降重,并且支持多种语言免费测句子的ai率,支持英文aigc报告等

下载
// ❌ 危险:TArray 的 value_type 是 FString,但 operator[] 返回的是 FString&
TArray Names = {TEXT("A"), TEXT("B")};
for (auto Name : Names) // 复制每项!大字符串开销高
{
    DoSomething(Name);
}

// ✅ 推荐:显式 const 引用避免拷贝
for (const FString& Name : Names)
{
    DoSomething(Name);
}

// ✅ 或用索引(当需要下标时)
for (int32 i = 0; i < Names.Num(); ++i)
{
    DoSomething(Names[i]);
}

额外注意:

  • TMap 的范围 for 迭代的是 TPair,不是 ValueType
  • 不要在循环中调用 Add()RemoveAt() —— UE 容器不保证迭代器失效行为与 STL 一致,可能跳项或崩溃

如何在蓝图暴露的函数中用现代 C++ 参数风格?

UE 的 UFUNCTION 反射不识别模板、概念或复杂别名。以下写法均无效:

  • UFUNCTION(BlueprintCallable) void SetData(TArrayView Data);TArrayView 不被蓝图识别)
  • UFUNCTION(BlueprintCallable) void Process(std::span Values);std::span 无反射信息)
  • UFUNCTION(BlueprintCallable) void Configure(const TMap& Config);(引用参数蓝图无法传入)

可行方案:

  • 输入统一用 const TArray&const TMap& —— UE 会自动转换蓝图数组/字典
  • 输出用 UPARAM(Ref) 标记的非 const 引用(如 UPARAM(Ref) TArray& OutPoints
  • 若需高性能只读视图,内部转成 TArrayView,但签名仍用 TArray

例如:

UFUNCTION(BlueprintCallable, Category = "Math")
void NormalizeVectors(const TArray& InVectors, TArray& OutNormalized);
// 内部可写:TArrayView View(InVectors);

最常被忽略的一点:UE 的 USTRUCT 成员变量即使声明为 const,也无法阻止蓝图或序列化修改它 —— 反射系统绕过 const 限定。真正想保护数据,得靠逻辑层校验或私有变量 + 公共 getter。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

557

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

98

2025.10.23

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

430

2024.06.27

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

72

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

280

2023.11.28

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

520

2023.09.20

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

175

2023.11.23

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

9

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.6万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号