C++ Unreal Engine如何使用智能指针TSharedPtr与TWeakObjectPtr

酷芳大大_7635

酷芳大大_7635

2026-10-21

518人浏览

原创

tsharedptr仅适用于非uobject类型,如fstring、自定义结构体或第三方sdk数据,用于跨线程共享且需引用计数管理;绝不可用于aactor等uobject子类,否则绕过gc导致悬空崩溃。

c++ unreal engine如何使用智能指针tsharedptr与tweakobjectptr

什么时候该用 TSharedPtr,而不是 TObjectPtr 或裸指针

UE5.4+ 推荐用 TObjectPtr 管理 UObject 子类,TSharedPtr 仅适用于非 UObject 类型(比如纯 C++ 数据结构、工具类、网络消息体)。硬用 TSharedPtr 持有 AActor 或 UActorComponent 会导致对象销毁后悬空,且无法被 GC 追踪——因为 TSharedPtr 不参与 UE 的引用计数机制。

常见错误现象:TSharedPtr<acharacter> PlayerRef;</acharacter> 编译能过,但角色被 Destroy 后指针仍非空,解引用直接 crash。

  • 只对继承自 UObject 的类型用 TObjectPtr 或 TWeakObjectPtr
  • TSharedPtr 适合封装 FString、自定义 FMyDataStruct、第三方 SDK 回调上下文等无生命周期托管需求的对象
  • 若需跨线程共享非 UObject 数据,TSharedPtr 是合理选择(它线程安全的引用计数)

TWeakObjectPtr 怎么避免访问已销毁的 UObject

TWeakObjectPtr 是 UE 对 UObject 的弱引用封装,不增加 GC 引用计数,访问前必须调用 IsValid() 或 Get() 判空。它不是“自动变 nullptr”,而是每次访问都查 Object 的内部标记位(IsPendingKill() + 是否已被 GC 清理)。

典型误用:if (WeakRef) { WeakRef->DoSomething(); } —— 这里隐式调用了 operator bool(),它只检查是否为空指针,**不检查 UObject 是否有效**,可能 crash。

  • 必须显式写 if (WeakRef.IsValid()) { WeakRef->DoSomething(); }
  • 在 Tick 或事件回调中频繁访问时,建议先 auto Obj = WeakRef.Get(); if (Obj) { ... },避免多次查表开销
  • 不能用 TWeakObjectPtr 延长 UObject 生命周期;它只是“观察者”,不是所有者

TSharedPtr 和 TWeakPtr 配合使用的正确姿势

当你要共享一个非 UObject 的资源(比如一个运行时生成的纹理缓存类 FCustomTextureCache),又需要避免循环引用导致内存泄漏,就得配对使用 TSharedPtr 和 TWeakPtr。

Kibana Saved Objects
Kibana Saved Objects

通过 REST API 管理 Kibana 保存的对象(仪表板、Lens 可视化等)。适用于:① 以编程方式创建、更新、删除仪表板和 Lens 可视化。

下载

错误示范:两个 TSharedPtr 互相持有对方,引用计数永远不归零,对象永不析构。

  • 所有权方用 TSharedPtr(例如管理器类里存 TSharedPtr<fcustomtexturecache></fcustomtexturecache>)
  • 被依赖方用 TWeakPtr(例如缓存项内部回调里存 TWeakPtr<ftexturemanager></ftexturemanager>)
  • 调用 TWeakPtr::Pin() 可临时转成 TSharedPtr,确保访问期间对象存活;但别滥用,Pin 失败会返回空 TSharedPtr
  • TWeakPtr 本身不参与构造/析构,开销极低,适合大量存储

UE 中混用智能指针的兼容性陷阱

UE 的智能指针不是标准库的 std::shared_ptr,它们不兼容。你不能把 TSharedPtr<int32></int32> 直接传给期望 std::shared_ptr<int32></int32> 的第三方库函数,反之亦然。

更隐蔽的问题是:UE 的 TSharedPtr 默认不支持自定义删除器(如 std::shared_ptr 的 Deleter 参数),也不能用 make_shared 构造——必须用 MakeShared()(注意大小写)。

  • 跨模块传递时,如果对方是纯 C++ 库,优先用裸指针 + 明确生命周期约定,或封装一层适配器
  • TSharedPtr::Reset() 会立即释放所有权,但不会触发 delete(除非引用计数归零),这点和 std::shared_ptr::reset() 行为一致
  • 在蓝图可调用函数(UFUNCTION)参数中,禁止使用任何 UE 智能指针类型——蓝图系统不识别它们,只能传 UObject* 或基本类型

最容易被忽略的是:TWeakObjectPtr 在多线程下 IsValid() 是线程安全的,但 Get() 返回的 UObject* 之后的所有操作,都需你自己保证线程安全——UE 不替你加锁。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1019

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

406

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ 手册教程
C++ 手册教程

共41课时 | 78.4万人学习

C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习