UE4之Delegate:单播

本文深入解析UE4中Delegate的单播机制,包括普通单播的定义,C++原生函数和UObject成员函数的绑定,以及执行过程。详细介绍了TBaseDelegate子类、IBaseDelegateInstance接口、FDelegateBase类,以及不同类型函数绑定的实现细节,如TBaseRawMethodDelegateInstance、TBaseUObjectMethodDelegateInstance和TBaseUFunctionDelegateInstance。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

普通单播的定义
#define DECLARE_DELEGATE( DelegateName ) FUNC_DECLARE_DELEGATE( DelegateName, void )
#define FUNC_DECLARE_DELEGATE( DelegateName, ... ) \
	typedef TBaseDelegate<__VA_ARGS__> DelegateName;
class TBaseDelegate<void, ParamTypes...>: public TBaseDelegate<TTypeWrapper<void>, ParamTypes...>
{
   
    // ···
}

实际上是一个TBaseDelegate子类, 看父类TBaseDelegate<TTypeWrapper, ParamTypes…>的定义

template <typename WrappedRetValType, typename... ParamTypes>
class TBaseDelegate : public FDelegateBase
{
   
public:
    /** 定义了返回的类型. */
    typedef typename TUnwrapType<WrappedRetValType>::Type RetValType;
    // 定义一个带有返回类型和参数的函数类型
    typedef RetValType TFuncType(ParamTypes...);
    /** 与此委托类兼容的委托实例类型的共享接口的类型定义. */
    typedef IBaseDelegateInstance<TFuncType> TDelegateInstanceInterface;

    FORCEINLINE TDelegateInstanceInterface* GetDelegateInstanceProtected() const
    {
   
	return (TDelegateInstanceInterface*)FDelegateBase::GetDelegateInstanceProtected();
    }
}

内部定义了一个与此委托类兼容的委托实例类型IBaseDelegateInstance,而IBaseDelegateInstance继承自IBaseDelegateInstanceCommon

struct IBaseDelegateInstanceCommon<RetType(ArgTypes...)> : public IDelegateInstance
{
   
    virtual void CreateCopy(FDelegateBase& Base) = 0;
    virtual RetType Execute(ArgTypes...) const = 0;
};

IBaseDelegateInstanceCommon的模板参数RetType和ArgTyes和TBaseDelegate里面的模板参数对应。

之后要介绍的绑定C++原生函数TBaseRawMethodDelegateInstance,绑定UObject对象成员函数TBaseUObjectMethodDelegateInstance,绑定UFunction的TBaseUFunctionDelegateInstance和绑定Lambada的TBaseFunctorDelegateInstance,都继承自IBaseDelegateInstance

然后讲一讲FDelegateBase,它是单播代理类的祖先类

class FDelegateBase
{
   
public:
    FDelegateBase& operator=(FDelegateBase&& Other)
    {
   
	Unbind();
	DelegateAllocator.MoveToEmpty(Other.DelegateAllocator);
	DelegateSize = Other.DelegateSize;
	Other.DelegateSize = 0;
        return *this;
    }
    FORCEINLINE IDelegateInstance* GetDelegateInstanceProtected( ) const
    {
   
        return DelegateSize ? (IDelegateInstance*)DelegateAllocator.GetAllocation() : nullptr;
    }
private:
    FDelegateAllocatorType::ForElementType<FAlignedInlineDelegateType> DelegateAllocator;
    int32 DelegateSize;
};

DelegateAllocator存储一个IDelegateInstance对象, 通过它来实现代理,获取代理的方式就是上面代码里的GetDelegateInstanceProtected(),这个方法会在TBaseDelegate里调用。

DelegateAllocator实际上是一个ForElementType类型, 继承自ForAnyElementType,MoveToEmpty方法,以级现在的GetAllocation方法,都是定义在ForAnyElementType中的

template<typename ElementType>
class ForElementType : public ForAnyElementType
{
   
public:
    FORCEINLINE ElementType* GetAllocation() const
    {
   
        // 调用基类的GetAllocation()方法
	return (ElementType*)ForAnyElementType::GetAllocation();
    }
};
class CORE_API ForAnyElementType
{
   
public:
    FORCEINLINE void MoveToEmpty(ForAnyElementType& Other)
    {
   
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值