代理允许您在C++对象上以通用的但类型安全的方式调用成员函数。通过使用代理,可以将其动态地绑定到任何对象的成员函数上,然后在该对象上调用函数,即时调用者不知道该对象的类型也没关系。

任何时候都应该通过引用传递代理。

声明代理

通过使用以下提供的任何一个宏都可以声明代理。所使用的宏由要绑定到该代理上的函数的签名决定。系统预定义了各种通用函数签名的组合、可以根据这些组合声明代理类型、给返回值及参数填入需要的任何类型的类型名称。现在支持使用以下任何条件组合的代理签名:

  • 返回一个值的函数

  • 多达4个"负载" 变量

  • 多达8个函数参数

  • 声明为 'const'的函数

 

函数签名

声明宏

void Function()

DECLARE_DELEGATE( DelegateName )

void Function( <Param1> )

DECLARE_DELEGATE_OneParam( DelegateName, Param1Type )

void Function( <Param1>, <Param2> )

DECLARE_DELEGATE_TwoParams( DelegateName, Param1Type, Param2Type )

void Function( <Param1>, <Param2>, ... )

DECLARE_DELEGATE_<Num>Params( DelegateName, Param1Type, Param2Type, ... )

<RetVal> Function()

DECLARE_DELEGATE_RetVal( RetValType, DelegateName )

<RetVal> Function( <Param1> )

DECLARE_DELEGATE_RetVal_OneParam( RetValType, DelegateName, Param1Type )

<RetVal> Function( <Param1>, <Param2> )

DECLARE_DELEGATE_RetVal_TwoParams( RetValType, DelegateName, Param1Type, Param2Type )

<RetVal> Function( <Param1>, <Param2>, ... )

DECLARE_DELEGATE_RetVal_<Num>Params( RetValType, DelegateName, Param1Type, Param2Type, ... )

绑定代理

代理系统理解某些对象类型,且当使用这些对象时会启用附加功能。如果您把一个代理绑定到一个UObject或共享的指针类上,代理系统可以保持一个到该对象的弱引用,以便当该对象在该代理的底层被销毁了时,您可以通过调用 IsBound() 或 ExecuteIfBound() 函数处理这些情况。注意,所支持的各种对象类型有特定的绑定语法。

 

函数

描述

Bind()

绑定到一个现有的代理对象上。

BindRaw()

绑定到一个原始的C++指针全局函数代理上。原始指针不使用任何引用,所以如果从代理的底层删除了该对象,那么调用它可能是不安全的。因此,当调用Execute()时一定要小心!

BindSP()

绑定一个基于共享指针的成员函数代理。共享指针代理保持到您的对象的弱引用。您可以使用 ExecuteIfBound() 来调用它们。

BindUObject()

绑定一个基于UObject的成员函数代理。UObject 代理保持到您的对象的弱引用。您可以使用 ExecuteIfBound() 来调用它们。

UnBind()

解除绑定该代理。

例如我在项目中遇到的:

GM->SPState->UpdateStateWidget.BindRaw(GameHUDWidget->PlayerStateWidget.Get(), &SSIAiPlayerStateWidget::UpdateStateWidget);

PlayerStateWidget继承自SWidget

ShortcutWidget->RegisterShortCutContainer.BindUObject(GM->SPState,&ASIAiPlayerState::RegisterShortCutContainer);

SPState为APlayerState子类,最终继承自UObject,所以使用BindUObject。

执行代理

绑定到代理上的函数可以通过调用代理的 Execute() 函数进行执行。在执行这些函数之前必须检查是否已经“绑定”了代理。这是为了使得代码更加安全,因为可能代理有时会具有未初始化且后续要访问的返回值及输出参数。执行一个未绑定的代理实际上有时会扰乱内存。可以调用 IsBound() 来判断执行该代理是否安全。同时,对于没有返回值的代理,您可以调用 ExecuteIfBound() 函数,但是一定要注意那些可能未初始化的输出参数。

 

执行函数

描述

Execute()

 

ExecuteIfBound()

 

IsBound()

UE4 代理 BindRaw和BindUObject的更多相关文章

  1. [UE4]代理事件(C++)

    用宏定义类似格式: DECLARE_DELEGATE //普通代理 DECLARE_DYNAMIC_DELEGATE_TwoParams //动态代理 DECLARE_DYNAMIC_MULTICAS ...

  2. UEC++ 代理/委托

    代理: 代理可以帮助我们解决一对一或是一对多的任务分配工作.主要可以帮助我们解决通知问题.我们可以通过代理完成调用某一个对象的一个函数,而不直接持有该对象的任何指针. 代理就是为你跑腿送信的,你可以不 ...

  3. [UE4]事件代理,无输出参数,蓝图中不需要绑定

    .h UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName = "LoginSuccess")) void LoginS ...

  4. [UE4]多播代理实例

    .h DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FLoginErrorEvent, FString, ErrorMessage); UPROPERTY(B ...

  5. [UE4]多播代理

    1. 第一种 DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FReceiveDelegateEvent, FString, Value1, FString, ...

  6. 全面理解UE4委托

    UE4中的delegate(委托)常用于解耦不同对象之间的关联:委托的触发者不与监听者有直接关联,两者通过委托对象间接地建立联系 监听者通过将响应函数绑定到委托上,使得委托触发时立即收到通知,并进行相 ...

  7. UE4技术总结——委托

    UE4技术总结--委托 目录 UE4技术总结--委托 一.定义 二.用法 2.1 声明与调用委托 2.1.1 单播委托 2.1.1.a 声明 2.1.1.b 绑定 2.1.1.c 执行委托 2.1.1 ...

  8. 【UE4 C++ 基础知识】<8> Delegate 委托

    概念 定义 UE4中的delegate(委托)常用于解耦不同对象之间的关联:委托的触发者不与监听者有直接关联,两者通过委托对象间接地建立联系. 监听者通过将响应函数绑定到委托上,使得委托触发时立即收到 ...

  9. UE4 WCF RestFul 服务器 读取JSON 数据并解析 简单实例

    Note:不知道为什么通过Txt读取的JsonString,如果TXT 不是ANSI编码的话,会报JsonArrayStringToUStruct  Unable to parse. bool UWg ...

随机推荐

  1. jQuery中ajax-$.getJSON,$.getScript

    jQuery提供了两个特定异步加载的方法$.getJSON()方法和$.getScript()方法 $.getJSON()来加载特定的json文件 $.getScript()来加载特定的javascr ...

  2. Django迁移数据库报错

    Django迁移数据库报错 table "xxx" already exists错误 django在migrate时报错django migrate error: table 'x ...

  3. GO代码生成代码小思小试

    推进需求 GO 项目,可整体生成一个运行文件到处跑,是极爽之事.但如果有资源文件要得带着跑,则破坏了这种体验. 例如下边这个项目结构,resource 目录下为资源文件,main.go 中会通过路径引 ...

  4. Linux 中 IDEA 不能调试(Debug)项目

    问题描述: can't debug project on idea linux. 在Linux 中, IDEA能运行项目,但是点击调试项目,弹出警告.警告内容如下: Required connecto ...

  5. 订Pizza(Java)

    帮朋友改的一个订pizza的作业 大概要求就是输入判断,选择pizza的个数和种类,然后返回一个价格 代码放在下面,如果有刚学Java的同学可以参考一下,没有什么难度 public class Piz ...

  6. 数据结构与算法---树结构(Tree structure)

    为什么需要树这种数据结构 数组存储方式的分析 优点:通过下标方式访问元素,速度快.对于有序数组,还可使用二分查找提高检索速度. 缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低 ...

  7. 西门子 S7-300 PLC 从入门到精通的100个经典问题

    1:使用CPU 315F和ET 200S时应如何避免出现“通讯故障”消息?   使用CPU S7 315F, ET 200S以及故障安全DI/DO模块,那么您将调用OB35 的故障安全程序.而且,您已 ...

  8. 【深入浅出-JVM】(序)

    本系列主要是让一个刚入门的 java 开发者,也能愉快的从零开始成为一个真正的 jvm 大神. 大纲 java 虚拟机的定义.总体架构.常用配置 垃圾回收算法.各类垃圾回收器 java 虚拟机对多线程 ...

  9. reportlab生成pdf

    文档地址:https://www.reportlab.com/docs/reportlab-userguide.pdf 源码地址:https://bitbucket.org/rptlab/report ...

  10. signed char类型取值范围计算

    在C语言程序中,给定一个类型,如何计算这个类型变量的取值范围呢?比如有一个字符型变量定义如下: signed char c: 这个字符变量c的取值范围是[-128,127],是计算出来的呢? 假设字符 ...