UEC++ 接口
词义广泛,用来陈述功能,选项,与其他程序结构进行沟通的方式。接口抽象出了交互结构,提供了两个未知逻辑交互的便捷性。对于编程中,如何更好的设计低耦合程序起到了至关重要的作用。设计者可以在互不关心的情况下,进行友好的程序设计,并且通过接口来完成设计的整合交互。
虚幻引擎中,加入了接口设计,从一定程度上“去掉了”多继承。接口可以帮助我们解决在不同类型的类之间却有相同行为的特性。接口的设计增加了代码编写的便捷性。
例如在设计射击类游戏时,我们需要子弹与场景中的物体进行交互,场景中的桌椅板凳,角色,怪物(都是独立的对象)都希望受到子弹的攻击伤害。那么子弹在打到目标后要逐一排查,审查目标是否属于上述的对象!这很麻烦!但是我们可以通过接口,增加上述目标具有受伤的能力。当子弹打到目标时,我只需要检查目标是否继承受伤的接口,如果有,则调用接口函数即可!
构建接口类:
我们可以直接在虚幻编辑器中继承接口类,然后完成构建
编写接口:
- 如果在C++中希望获得接口能力,则需要继承接口。需要注意的是,必须继承I开头的接口名称,并且继承修饰为public。不要尝试重写接口中的函数!
- 如果接口中的函数使用BlueprintNativeEvent说明,则在继承类中可以编写同名函数,并用后缀“_Implementation”进行标记。
- 如果接口中的函数使用BlueprintImplementableEvent说明,则无法在C++的继承类中实现接口函数
实现接口:
继承I类接口完毕后,可以选择的将接口中的函数进行定义。如果需要定义,则需要将接口中函数说明是BlueprintNativeEvent的函数进行定义。
注意,不要省略override,函数的返回值,参数列表需要和接口的一致
调用操作:
调用函数,持有继承接口对象指针,第一步先转换到I类指针,调用Execute_接口函数名,参数第一位需要传递原对象指针,后面直接按照原函数参数填入即可
整体代码演示:
// TestInterface.h
UINTERFACE(MinimalAPI)
class UTestInterface : public UInterface
{
GENERATED_BODY()
}; /**
* 1、U类中不能去写接口函数,只能用来检查是否继承了接口类
* 2、接口函数,必须写在I类中,并且必须写共有域中
* 3、接口函数在接口类中不能进行定义
*
*/
class MX_API ITestInterface
{
GENERATED_BODY() // Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
// 定义接口函数
UFUNCTION(BlueprintNativeEvent)
void Notify_None();
UFUNCTION(BlueprintNativeEvent)
int32 Notify_RetVal();
UFUNCTION(BlueprintNativeEvent)
int32 Notify_RetVal_Params(int32 Num);
}; /////////////////////////////////////////////////////////////
// Actor2.h
public:
// Called every frame
virtual void Tick(float DeltaTime) override; // 实现接口
virtual void Notify_None_Implementation() override;
virtual int32 Notify_RetVal_Implementation() override;
virtual int32 Notify_RetVal_Params_Implementation(int32 Num) override; // Actor2.cpp
void AActor2::Notify_None_Implementation()
{
UKismetSystemLibrary::PrintString(this, TEXT("----无参无返回值----"));
} int32 AActor2::Notify_RetVal_Implementation()
{
UKismetSystemLibrary::PrintString(this, TEXT("----无参有返回值----"));
return 0;
} int32 AActor2::Notify_RetVal_Params_Implementation(int32 Num)
{
UKismetSystemLibrary::PrintString(this, TEXT("----有参有返回值----"));
return Num;
}void AActor2::Notify_None_Implementation()
{
UKismetSystemLibrary::PrintString(this, TEXT("----无参无返回值----"));
} int32 AActor2::Notify_RetVal_Implementation()
{
UKismetSystemLibrary::PrintString(this, TEXT("----无参有返回值----"));
return 0;
} int32 AActor2::Notify_RetVal_Params_Implementation(int32 Num)
{
UKismetSystemLibrary::PrintString(this, TEXT("----有参有返回值----"));
return Num;
}
/////////////////////////////////////////////////////////
//Actor1.cpp
ac2 = GetWorld()->SpawnActor<AActor2>(AActor2::StaticClass());
// 检查是否继承了接口
ITestInterface* testInterface = Cast<ITestInterface>(ac2);
// 如果继承了接口,就执行接口函数
if (testInterface) {
testInterface->Execute_Notify_None(ac2);
testInterface->Execute_Notify_RetVal(ac2);
testInterface->Execute_Notify_RetVal_Params(ac2,10);
}
测试结果:
包裹接口:
借助模板类TScriptInterface可以将接口包裹,用于使用UPROPERTY描述,并且可以暴露到蓝图中。使用时同普通接口一样使用。接口不支持智能指针的管理,所以需要使用TS类进行管理
UPROPERTY(EditAnywhere)
TScriptInterface<ITestInterface> TestInterface;
蓝图继承接口:
如果接口在蓝图中被继承,则需要注意下面的问题
- 如果函数没有返回类型,则在蓝图中当作事件Event使用
- 如果函数存在返回类型或是存在传递引用参数,则在蓝图中当作函数使用
- 接口函数说明符使用BlueprintNativeEvent或是BlueprintImplementableEvent标记都可以在蓝图中找到
总结:
- 接口函数需要定在I开头的类中,不要修改访问域public关键字,声明需要使用宏标记BlueprintNativeEvent或BlueprintImplementableEvent
- 如需继承接口,继承I类,继承关系public
- 接口中的函数禁止重写
- 在继承类中实现接口函数,并添加后缀_Implementation,需要注意,函数前加入虚函数关键字virtual,函数结尾加override关键字(可以不添加,但是建议加上,加强函数编写正确性检查),在CPP文件中实现逻辑
- 调用函数,持有继承接口对象指针,第一步先转换到I类指针,调用Execute_接口函数名,参数第一位需要传递原对象指针,后面直接按照原函数参数填入即可
- 检查某一个类是否实现了对应接口可以使用如下语法进行检查
- obj->GetClass()->ImplementsInterface(U类型::StaticClass());
- act->GetClass()->ImplementsInterface(UMyInterface::StaticClass());
- act是对象指指针
接口的优缺点:
优点:
- 具备多态特性,接口衍生类支持里氏转换原则
- 接口可以使得整个继承系统更加的干净单一
- 接口可以规范类的具体行为
- 接口可以隔离开发中的开发耦合,我们只需要针对接口去编码,无需关心具体行为
- 接口继承可以使得继承关系中出现真正的操作父类
缺点:
- 丢失了C++中的广泛继承特性
- 接口拘束了类型的属性拓展,无法进行更详细的内容定义
- 继承关系中容易让人混淆,接口本身不具备真正的继承特性
UEC++ 接口的更多相关文章
- Atitit 纯java项目的提升进度大法---通用json dsl接口
Atitit 纯java项目的提升进度大法---通用json dsl接口 1. Json dsl接口1 1.1. Url: http://aaa.com/api_jsondsl?dsl={}1 1. ...
- Atitit mybatis快速开发 的sql api接口
Atitit mybatis快速开发 的sql api接口 1.1. sql模式 开发速度大大快与 映射模式1 1.2. MyBatis Mapper1 1.2.1. 代码2 1.2.2. 原理2 1 ...
- Atitit 通用接口的设计与实现attilax 总结
Atitit 通用接口的设计与实现attilax 总结 1.1. 现存的情况1 1.2. 接口返回类型,与返回序列化格式1 1.3. 异常传递 代替返回值模式1 1.4. 通用接口原理1 1.5. A ...
- App开发:模拟服务器数据接口 - MockApi
为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...
- 干货来袭-整套完整安全的API接口解决方案
在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...
- 12306官方火车票Api接口
2017,现在已进入春运期间,真的是一票难求,深有体会.各种购票抢票软件应运而生,也有购买加速包提高抢票几率,可以理解为变相的黄牛.对于技术人员,虽然写一个抢票软件还是比较难的,但是还是简单看看123 ...
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Java基础Map接口+Collections
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- java基础_集合List与Set接口
List接口继承了Collection的方法 当然也有自己特有的方法向指定位置添加元素 add(索引,添加的元素); 移除指定索引的元素 remove(索引) 修改指定索引的元素 set ...
随机推荐
- Docker容器搭建android编译环境
Docker容器搭建android编译环境 目录 1 部署容器 1.1 手动部署 1.1.1 配置docker 1.1.2 启动容器 1.1.3 配置环境 1.2 Dockerfile 2 镜像管理 ...
- 字符串压缩(二)之LZ4
本文来自博客园,作者:T-BARBARIANS,转载请注明原文链接:https://www.cnblogs.com/t-bar/p/16451185.html 谢谢! 上一篇对google精品ZSTD ...
- Go死锁——当Channel遇上Mutex时
背景 用metux lock for循环,在for循环中又 向带缓冲的Channel 写数据时,千万要小心死锁! 最近,我在测试ws长链接网关,平均一个星期会遇到一次服务假死问题,因为并不是所有rou ...
- 多线程与高并发(一)—— 自顶向下理解Synchronized实现原理
一. 什么是锁? 在多线程中,多个线程同时对某一个资源进行访问,容易出现数据不一致问题,为保证并发安全,通常会采取线程互斥的手段对线程进行访问限制,这个互斥的手段就可以称为锁.锁的本质是状态+指针,当 ...
- 对比学习下的跨模态语义对齐是最优的吗?---自适应稀疏化注意力对齐机制 IEEE Trans. MultiMedia
论文介绍:Unified Adaptive Relevance Distinguishable Attention Network for Image-Text Matching (统一的自适应相关性 ...
- [NOIP2015 提高组] 运输计划题解
题目链接:P2680 [NOIP2015 提高组] 运输计划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 看了好长时间题解才终于懂的,有关lca和二分答案的题解解释的不详细,一时 ...
- .net6与英雄联盟邂逅之——根据官方LCU API制作游戏助手
看了网上很多自己开发的英雄联盟的小助手工具,当时苦于没有api,自己也想做一个.后来发现了其实拳头本身就提供了LCU API在客户端运行的时候会暴露出来. 现在我们就来了解下工具的实现. 查询数据:h ...
- 密码学的基础:X.690和对应的BER CER DER编码
目录 简介 BER编码 类型标识符 长度 内容 CER编码和DER编码 总结 简介 之前我们讲到了优秀的数据描述语言ASN.1,很多协议标准都是使用ASN.1来进行描述的.对于ASN.1来说,只定义了 ...
- Mpvue1.0+Python3.7+Django2.0.4实现微信小程序的支付功能
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_112 其实微信支付有很多种形式,刷脸,扫码,APP支付,小程序支付等,这边只说明小程序支付的实现,不过原理上都大同小异. 首先,需 ...
- 石火电光追风逐日|前端优化之次时代图片压缩格式WebP的项目级躬身实践(Python3 PIL+Nginx)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_190 我们知道,在前端界有一个共识:速度就是生命,带宽就是金钱.怎样将页面加载速度有效提升是无数前端工程师无时不刻在思考的课题,目 ...