在UE4中实现虚函数

对C++有些了解的同学都知道虚函数的实现方式如下

class A
{
public:
    virtual void Init();
};

class B: public A
{
public:
    virtual void Init() override;
};

这样A的Init就是一个虚函数并且可以被子类Override了。

在UE4中实现C++类之间的虚函数,也是同上的方式,稍微特别的一点的是,C++中如何实现一个既可以被C++子类Override也可以被蓝图子类的Override的虚函数?稍微查一下UE4的文档,我们了解到BlueprintNativeEvent这个关键字,可以实现我们的需求,大致代码如下

class A
{
public:
	UFUNCTION(BlueprintNativeEvent)
		void Init();
	virtual void Init_Implementation();
};

class B:public A
{
public:
	virtual void Init_Implementation() override;
};

这样C++之间即AB之间的虚函数通过Init_Implementation来处理,C++类和蓝图子类之间的虚函数通过Init来处理,A的蓝图子类可以通过重写Init来覆盖掉父类的实现。

按理来说,UE4中实现虚函数到此可以结束讨论了,偏偏我在发现BlueprintNativeEvent之前自己捏造了一个类似的虚函数实现,大致代码如下

class A
{
public:
	    virtual void Init()    {    InitBP();    };
    UFUNCTION(BlueprintImplementableEvent)
	    void InitBP();
};

class B:public A
{
public:
	virtual void Init() override;
};

这里C++之间即AB之间的虚函数通过Init来处理,C++类和蓝图子类之间的虚函数通过InitBP来处理,A的蓝图子类可以通过实现InitBP来实现Init的功能。

咋一看,好像和UE4提供的解决方案差不多?仔细一想,差别很大,还是UE4提供的解决方案更好!原因如下:

  1. 第二种方案可以实现C++和C++之间的虚函数功能,但对于C++和蓝图之间的虚函数解决得并不好。它只是将Init开放给了蓝图实现,但是并没有将更重要的Override开放给蓝图!即使蓝图实现了InitBP,蓝图也无法修改C++基类A的Init实现,而这在虚函数设计中,是非常重要的一点,即子类可以完全将父类中的虚函数控制权夺取过来。这个缺点在实际开发中的体现就是,如果我想在A的子类蓝图中完全构造Init并且抛弃掉A中Init的实现,那么是无法做到的!这。。很不虚函数!
  2. 在我们承认了第1点的缺陷情况下,即我们认定C++中的Init绝不会修改,蓝图类只需要自己添加InitBP实现即可,第二个问题又来了!这个问题还很严重:Init只能在C++中调用,无法被蓝图调用!开始我想,好嘛,这个简单,给Init加一个UFUNCTION(BlueprintCallable)不就可以了嘛!接下来。。UE4编译报错:Override of UFUNCTION in parent class (A) cannot have a UFUNCTION() declaration above it!原来UE4中一旦将一个函数标志为了UFUNCTION(BlueprintCallable),那么这个函数就自动失去了虚函数的属性,无法被C++子类重写。这个方法行不通了!修补方法失败。。

所以,想在UE4中实现C++之间、C++蓝图之间的虚函数,还是老实地按照BlueprintNativeEvent来做吧。

当然了,如果你的需求恰好是将部分实现开放给蓝图并且基础C++实现不能被蓝图修改,那么第二种方案倒正可以解决这个问题。

注:蓝图子类实现了Init之后,会完全替换掉A的Init_Implementation(),如果还想在蓝图中使用基类的Init_Implementation()实现的话,那么Add Call to Parent Function即可,类似于C++的Super::Init()。

 

 

 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值