memnew 宏
memnew 是一个宏,用于自定义对象的内存分配和初始化。其写法如下:
#define memnew(m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", "") m_class))解释如下:
new ("", "") m_class:调用了自定义的operator new,传递了两个字符串参数(实际用作避免与引擎的operator new冲突),用于分配内存。::godot::_pre_initialize<...>():在分配前做一些类型相关的初始化(模板元编程,通常为空实现)。::godot::_post_initialize(...):在对象构造后做一些后处理(比如注册、钩子等),并返回对象指针。- 逗号表达式保证先执行
_pre_initialize,再执行_post_initialize并返回其结果。
这样做的目的是:
- 统一对象的分配和初始化流程,便于内存管理和调试。
- 支持 Godot 的自定义内存分配策略。
memdelete 宏
Ref
Ref 是一个模板类,用于管理 Godot 引擎中继承自 RefCounted 的对象的引用计数。它的主要作用是自动管理对象的生命周期,防止内存泄漏和悬挂指针。
核心要点如下:
Ref<T>持有一个指向类型为T(通常继承自RefCounted)的指针reference。- 通过引用计数机制,
Ref会在对象无人引用时自动释放内存。 - 支持拷贝、赋值、比较、指针操作(如
->和*),用法类似智能指针。 - 提供
is_valid()和is_null()方法判断引用是否有效。 - 构造、赋值和析构时会自动增加或减少引用计数。
- 适用于 Godot C++ 扩展开发中资源和对象的安全管理。
简而言之,Ref 是 Godot C++ 绑定中的智能引用计数指针,专为 Godot 对象安全管理而设计。
为什么不直接使用智能指针(如
std::shared_ptr)?
Ref没有直接用std::shared_ptr主要原因如下:
- Godot 的对象系统需要自定义的引用计数逻辑(如
reference()/unreference()),以便与引擎的生命周期和信号机制集成。- Godot 对象有特殊的类型转换、绑定和垃圾回收需求,
Ref支持 Godot 的类型安全和对象查找。std::shared_ptr不支持 Godot 的Variant、信号、资源系统等特性。- Godot 需要跨语言(如 GDExtension、脚本)一致的对象管理,
Ref设计为与 Godot 内部一致。简言之,
Ref是为 Godot 引擎量身定制的智能指针,满足其特殊需求,而std::shared_ptr无法直接满足这些需求。