对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()。

在UE4中实现虚函数相关推荐

  1. C++中最好不要在构造函数和析构函数中调用虚函数!!!

    1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...

  2. C++对象模型8——构造函数和析构函数中对虚函数的调用、全局对象构造和析构、局部static数组的内存分配

    一.构造函数和析构函数中对虚函数的调用 仍然以https://blog.csdn.net/Master_Cui/article/details/109957302中的代码为例 base3构造函数和析构 ...

  3. C++中的虚函数与纯虚函数

    文章目录 1 C++中的虚函数 1.1 虚函数 1.2 单个类的虚函数表 1.3 使用继承的虚函数表 1.4 多重继承的虚函数表 2 C++中的纯虚函数 1 C++中的虚函数 1.1 虚函数 虚函数的 ...

  4. C# 构造函数中调用虚函数

    C# 构造函数中调用虚函数 using System; using System.Diagnostics; using System.Text; using System.Collections; u ...

  5. C++中的虚函数(virtual function)

    1回顶部 一.简介 虚函数是C++中用于实现多态(polymorphism)的机制.核心理念就是通过基类访问派生类定义的函数.假设我们有下面的类层次: class A { public: virtua ...

  6. C++学习笔记-----不要在构造函数和析构函数中调用虚函数

    考虑下面的程序: #include <iostream> using namespace std;class Base { public:Base() { cout << &q ...

  7. C++学习笔记-----永远不要在派生类中改变虚函数的默认参数值

    提到虚函数,我们就会自然而然的想到多态,但是当虚函数中存有默认参数值的时候,在派生类中重定义这个虚函数时不可以改变这个参数的值. 请看下面的例子: #include "stdafx.h&qu ...

  8. C++中最好不要在构造函数和析构函数中调用虚函数

    1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...

  9. MFC中关于虚函数的一些问题

    这个是C++中虚函数以及多态性. 我们知道,如果派生类中重定义了基类中的虚函数,即使用基类的类型指针调用该函数,那么实际上连编的是派生类的函数.比如, class A { virtual void o ...

最新文章

  1. AI 一分钟 | 谷歌发布72量子比特处理器,或将为机器学习应用提供加速;百度已经发起对景驰撤诉,但不会对王劲撤诉
  2. javaScript数据类型(包括基本数据类型和非基本数据类型)
  3. 上海市名校一年级数学考试附加题,难住学霸
  4. comsol显示电场计算结果_在 COMSOL 中构建磁流体动力学多物理场模型
  5. 【王道考研操作系统】—文件的基本操作
  6. python是一种代表简单主义思想的语言_setuptools-36.6.0
  7. Python基于共现提取《釜山行》人物关系
  8. Webservice工具soapUI下载和使用
  9. 分手后如何忘掉你的前任1
  10. javaee实训报告总结_javaee实习报告.doc
  11. 用idea对git的merge进行撤销
  12. Oracle中动态SQL详解(EXECUTE IMMEDIATE)
  13. C#调用Qt写的dll,并处理异常来自 HRESULT:0x8007000B
  14. 基于李雅普诺夫函数的跟踪控制(一)
  15. maven3实战之仓库
  16. 基于SSM的学生考勤管理系统的设计与实现
  17. 苹果M1芯片曝重大Bug:大量用户4K显示器中招,系统兼容性有问题
  18. 【跨境电商】5个最佳免费极简主义WordPress主题(一)
  19. 泳池马赛克让你徜徉在在海洋般的湛蓝与天际之间
  20. centos7 安装 nodejs 16

热门文章

  1. c++计算正态累积分布函数
  2. element-ui中switch开关回显问题
  3. 本地怎么连接服务器的mysql_本地如何连接到服务器上的MySQL
  4. 牛客 旋变字符串问题
  5. WPF实现水面波纹特效
  6. css 波纹扩散_css3实现支付宝波纹扩散的功能原理
  7. 大数据在电力行业的应用案例100讲(二十三)-敏感性分析在园区能源互联网项目经济评价中的应用
  8. 初学者vscode+latex笔记
  9. android实现MP3播放器
  10. Word进行自动生成目录右边页面等格操作简单详细方法