UE4 C++ 动态绑定函数的几种实现方法(一)

UE4 C++动态绑定函数的几种实现方法

一、基本实现方案

1、使用TFunction以及Lambda表达式

1.1 在DeleClass定义TFunction
TFunction<void(FString)> TFunOne;
//绑定TFunOne的函数
void RegFunOne(TFunction<void(FString)> TargetFun)
{
	TFunOne = TargetFun;
	//在任何想要的地方实现该方法
	TFunOne(FString(“RegFunOne”));
}
1.2 在ReceClass声明并定义要执行的函数
void ReceClass::EchoInfoOne(FString InfoStr)
{
	//自己写的Debug函数
	Debug(InfoStr,500.f);
}
1.3 在ReceClass将要执行的函数绑定到TFunction
DeleClass::RegFunOne([this](FString InfoStr){ EchoInfoOne(InfoStr);});
1.4 执行流程:
  1. ReceClass调用DeleClass::RegFunOne,利用lambda生成一个函数指针作为参数传入
  2. DeleClass执行RegFunOne,将获取到的函数指针赋值给TFunOne,此时TFunOne已经有具体函数实例
  3. 实现类中特定函数的动态绑定

2、使用无参数委托

2.1 在DeleClass定义接收函数的委托以及绑定函数
//声明一个无参数最简单的静态委托
DECLARE_DELEGATE(FWDE_Single_Zero)

/*
* 绑定其他类中的函数
* @param TarObj 要绑定函数的类的实例
* @param InMethod TarObj中某个类void(FString,int32)函数的指针
*/
template<class UserClss>
void DeleClass::RegFunTwo(UserClass* TarObj,
			typenameTMemFunPtrType<false,UserClass,void(FString,int32)>::Type InMethod)
{
	//定义一个委托
	FWDE_Single_Zero ExeDel;
	//将委托绑定到传入的函数中
	ExeDel.BindUObject(TarObj,InMethod,FString("RegFunTwo"),54);
	//执行委托
	ExeDel.ExecuteIfBound();
}
2.2在ReceClass执行绑定函数
void ReceClass::EchoInfoTwo(FString InfoStr,int32 Count)
{
	Debug(InfoStr+FString::FromInt(Count),500.0f);
}

DeleClass->RegFunTwo(this,&AFWReceActor::EchoInfoTwo);
2.3 执行流程
  1. ReceClass调用DeleClass::RegFunTwo,并将自身以及需要绑定的函数传入
  2. DeleClass定义一个0参数委托,并利用BindUObject绑定RegFunTwo传入的函数
  3. 执行委托对象

    缺点:只能在绑定时传入参数而不是在运行时

3、使用多参数委托(TUObjectMethodDelegate)

3.1 在DeleClass定义接收函数的委托以及绑定函数
//声明一个无参数最简单的静态委托
DECLARE_DELEGATE_TwoParams(FWDE_Single_Two,FString,int32)


template<class UserClss>
void DeleClass::RegFunThree(UserClass* TarObj,
			typename FWDE_Single_Two::TUObjectMethodDelegate<UserClass>::FMeshodPtr InMethod)
{
	//定义一个委托
	FWDE_Single_Two ExeDel;
	//将委托绑定到传入的函数中
	ExeDel.BindUObject(TarObj,InMethod);
	//执行委托
	ExeDel.ExecuteIfBound(FString("RegFunThree"),54);
}
3.2 在ReceClass执行绑定函数
void ReceClass::EchoInfoThree(FString InfoStr,int32 Count)
{
	Debug(InfoStr+FString::FromInt(Count),500.0f);
}

DeleClass->RegFunTwo(this,&AFWReceActor::EchoInfoThree);
3.3 执行流程
  1. ReceClass调用DeleClass::RegFunThree,并将自身以及需要绑定的函数传入
  2. DeleClass定义一个0参数委托,并利用BindUObject绑定RegFunTwo传入的函数
  3. 执行委托对象

二、用于开发的泛型化

1 利用泛型建立一个统一的接口

1.1 在DeleClass声明并定义泛型接口
template<class DelegateType, class UserClass, typename... VarTypes>
void RegFunFour(UserClass *TarObj,
			typename DelegateType::templete TUObjectMethodDelegate<UserClass>::FMethodPtr InMethod,
			VarTypes... Vars)
{
	FWDE_Single_Zero ExeDel;
	ExeDel.BindUObject(TarObj,InMethod,Vars...);
	ExeDel.ExecuteIfBound();
}
1.2 在ReceClass中使用该泛型接口
DECLARE_DELEGATE_TwoParams(FTempDele,FString,int32)

/*
* TempDele 确定委托类型
* EchoInfoTwo 要绑定的函数
* Fstring("")/56 传入的参数
*/
DeleClass->RegFunFour<TempDele>(this,&ReceClass::EchoInfoTwo,FString("RegFunFour"),56);

2 利用泛型实现TFunction的扩展

2.1 在DeleClass中声明并定义接口
template<typename RetType,typename... varTypes>
void DeleClass::RegFunFive(TFunction<RetType(VarTypes...)> TarFun)
{
	if(TarFun("RegFunFive",78))
		Debug("return true",500.f);
}
2.2 在ReceClass中声明并定义接口
bool ReceClass::EchoInfoThree(FString InfoStr,int32 COunt)
{
	Debug(InfoStr+FString::FromInt(COunt),500.f);
	return true;
}
//调用该接口
DeleClass->RegFunFive<bool,FString,int32>([this](FString InfoStr,int32 Count){
	return EchoInfoThree(InfoStr,Count);
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值