当然,Unreal Engine 4 提供了一系列宏来声明和定义各种类型的委托。我会列出主要的几种并简要解释它们: 1. **DECLARE_DELEGATE**: 用于声明一个没有参数的单播委托。 示例: ```cpp DECLARE_DELEGATE(FMySimpleDelegate); ``` 2. **DECLARE_DELEGATE_OneParam**、**DECLARE_DELEGATE_TwoParam** 等: 用于声明带有参数的单播委托。数字指的是参数的数量。 示例: ```cpp DECLARE_DELEGATE_OneParam(FMyDelegateWithOneParam, int32); ``` 3. **DECLARE_DYNAMIC_DELEGATE**: 声明一个可以被蓝图使用的、没有参数的单播委托。动态委托需要更多的开销,但可以与蓝图系统交互。 示例: ```cpp DECLARE_DYNAMIC_DELEGATE(FMyDynamicDelegate); ``` 4. **DECLARE_DYNAMIC_DELEGATE_OneParam**、**DECLARE_DYNAMIC_DELEGATE_TwoParam** 等: 声明可以被蓝图使用的、带有参数的单播委托。 示例: ```cpp DECLARE_DYNAMIC_DELEGATE_OneParam(FMyDynamicDelegateWithParam, FString, Name); ``` 5. **DECLARE_MULTICAST_DELEGATE**: 用于声明一个没有参数的多播委托。多播委托允许绑定多个函数,并在广播时按顺序调用。 示例: ```cpp DECLARE_MULTICAST_DELEGATE(FMyMulticastDelegate); ``` 6. **DECLARE_MULTICAST_DELEGATE_OneParam**、**DECLARE_MULTICAST_DELEGATE_TwoParam** 等: 用于声明带有参数的多播委托。 示例: ```cpp DECLARE_MULTICAST_DELEGATE_OneParam(FMyMulticastDelegateWithParam, float); ``` 7. **DECLARE_DYNAMIC_MULTICAST_DELEGATE**: 声明一个可以被蓝图使用的、没有参数的多播委托。 示例: ```cpp DECLARE_DYNAMIC_MULTICAST_DELEGATE(FMyDynamicMulticastDelegate); ``` 8. **DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam**、**DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParam** 等: 声明可以被蓝图使用的、带有参数的多播委托。 示例: ```cpp DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyDynamicMulticastWithParam, FVector, Direction); ``` 这些宏使得在UE4中使用委托变得非常简单和直观。选择正确的委托类型取决于你的具体需求,例如是否需要与蓝图交互、是否需要多播功能等。 1. 单播委托 2. 多播委托 3. 动态代理委托 4. 动态多播代理委托 5. 事件 # 单播委托 只能绑定一个函数指针的委托,只能触发一个绑定的回调 在UE(Unreal Engine)中,单播委托提供了两种绑定lambda表达式的方法:`BindLambda` 和 `BindWeakLambda`。这两者的核心差异在于它们处理对象生命周期的方式。 1. **BindLambda**: 当你使用`BindLambda`绑定一个lambda到委托时,lambda捕获的任何对象都会被强引用。这意味着,只要委托仍然存在并引用该lambda,那么lambda捕获的所有对象都不会被垃圾回收。这可以确保委托被触发时,lambda中引用的所有对象都是可用的。然而,这也可能导致一些非预期的内存泄漏,特别是在长时间持有委托的情况下。 2. **BindWeakLambda**: `BindWeakLambda`提供了一种更加安全的方式来绑定lambda,尤其是在处理UObjects时。当你使用`BindWeakLambda`时,lambda捕获的UObjects会被弱引用。这意味着,如果UObject在某个时刻被垃圾回收了,当你尝试触发委托时,该lambda将不会执行。这可以防止在访问已经被销毁的对象时出现无效的内存访问。 总结: - 使用`BindLambda`时,要确保你了解和管理lambda的生命周期以及它捕获的所有对象。 - 当处理UObjects或当你不确定对象的生命周期时,最好使用`BindWeakLambda`来确保内存安全。 为了方便理解,以下是一些中英文术语对照: - 委托 (Delegate):在Unreal Engine中,委托是一种对象,它可以安全地引用类的成员函数,并可以在需要时调用它。 - Lambda表达式 (Lambda Expression):一个可以捕获其环境的匿名函数对象。 - 强引用 (Strong Reference):对对象的一种引用,只要这种引用存在,对象就不会被垃圾回收。 - 弱引用 (Weak Reference):对对象的一种引用,不会阻止对象被垃圾回收。 # 事件 只属于某一个类的。 当定义事件后,需要指定响应事件的类 内部代码将作用类设定成了事件类的友元类。 ```CPP //无参事件 DECLRE_EVENT(类名,事件名); //实例化 事件名事件实例名; ``` ==事件不能有返回值== ==多播委托也不能有返回值== 动态代理和动态多播代理 可以在蓝图中使用,但是效率低