当然,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(类名,事件名);
//实例化
事件名事件实例名;
```
==事件不能有返回值==
==多播委托也不能有返回值==
动态代理和动态多播代理
可以在蓝图中使用,但是效率低