在这里插入图片描述

implement_ex宏是 Arm-2D 库中用于面向对象编程(OOP)支持的核心宏定义。

implement_ex 宏的定义和作用

implement_ex 宏在 Library/Include/arm_2d_utils.h 中定义,用于在 C 语言中实现类似继承的功能:


/*!* \note do NOT use this macro directly*/
#ifdef   __cplusplus
#   define __implement_ex(__type, __name)   __type  __name
#else
#   define __implement_ex(__type, __name)                                       \union {                                                             \__type  __name;                                                 \__type;                                                         \}
#endif
/*!* \note do NOT use this macro directly*/
#define __implement(__type)             __implement_ex( __type,                 \
/*!* \brief inherit a given class* \param __type the base class, you can use .use_as_xxxxx for referencing *               the base.* \note this macro supports microsoft extensions (-fms-extensions)*/
#define implement(__type)               __implement(__type)/*!* \brief inherit a given class and give it an alias name* \param __type the base class* \param __name an alias name for referencing the base class* \note this macro supports microsoft extensions (-fms-extensions)*/
#define implement_ex(__type, __name)    __implement_ex(__type, __name)

该宏的具体实现根据编译器环境有所不同:

  • C++ 环境下:直接定义为普通的结构体成员
  • C 环境下:使用匿名联合体来实现成员访问的灵活性

实际使用示例

在 Arm-2D 的数据结构中,implement_ex 被广泛使用。例如在 arm_2d_region_t 结构体中:

 /*!* \brief a type for an rectangular area**/
typedef struct arm_2d_region_t {implement_ex(arm_2d_location_t, tLocation); //!< the location (top-left corner)implement_ex(arm_2d_size_t, tSize);         //!< the size
} arm_2d_region_t;

这里 implement_ex(arm_2d_location_t, tLocation) 表示该结构体继承自基类 arm_2d_location_t,可以通过 tLocation来访问这个基类的成员

与其他相关宏的关系

implement_ex 是一系列 OOP 支持宏的一部分:

  • implement(__type) - 不指定别名的继承
  • implement_ex(__type, __name) - 指定别名的继承
  • inherit(__type)inherit_ex(__type, __name) - 不支持 Microsoft 扩展(-fms-extensions)的版本
    inherit主要作用是:当基类里的成员名称与派生类中的成员名称,或者进行多继承的时候,多个基类里的成员名称存在冲突时,就要使用 inherit 来避免问题。如果不存在冲突时,应该尽可能使用 implement和implement_ex

了解如上的作用和定义后,要完全理解它的功能,我们需要两个基本知识:

匿名结构和联合体的定义和使用

在C语言中,可以定义匿名结构体或联合体,这通常用于创建复杂的数据类型,而不需要为每个单独的成员定义一个名称。
匿名结构体和联合体通常用于以下场景:

  • 简化代码:当不需要为结构体或联合体的每个成员单独命名时,可以使用匿名类型来简化代码。

  • 嵌套类型:在定义更复杂的数据结构时,可以使用匿名类型来避免重复定义相同的结构体或联合体。

  • 接口定义:在定义函数接口时,可以使用匿名类型来定义参数或返回值的结构
    正常结构体定义(联合体union类似,不再赘述):

struct tagVar{int a;float b;
} var1;

匿名结构体定义(联合体union类似,不再赘述):

struct {int a;float b;
} var1;

两者唯一的区别就在前者多了tagVar名字,我们可以使用如下方式再次定义其他结构变量:

struct tagVar Var2;

而后者由于没有具体的名称,所以我们无法再次用它去定义其他变量。

Microsoft 扩展(-fms-extensions)

Microsoft 扩展的作用是对匿名结构体(或者联合体)的进一步展开支持,为了理解它的作用,我们以arm2d中的一个数据结构定义arm_2d_region_t 的定义为例来说明其作用:
该结构体定义如下:

/*!* \brief a type for an rectangular area**/
typedef struct arm_2d_region_t {implement_ex(arm_2d_location_t, tLocation); //!< the location (top-left corner)implement_ex(arm_2d_size_t, tSize);         //!< the size
} arm_2d_region_t;

我们将宏implement_ex展开,得到如下代码:

typedef struct arm_2d_region_t {  // 展开 implement_ex(arm_2d_location_t, tLocation)  union {  arm_2d_location_t tLocation;    //!< the location (top-left corner)  arm_2d_location_t;              //!< 匿名成员  };  // 展开 implement_ex(arm_2d_size_t, tSize)    union {  arm_2d_size_t tSize;           //!< the size  arm_2d_size_t;                 //!< 匿名成员};  
} arm_2d_region_t;

对于以上代码,我们就可以采用如下方式进行成员访问:

arm_2d_region_t region;  // 通过命名成员访问  
region.tLocation.iX = 10;  
region.tLocation.iY = 20;  
region.tSize.iWidth = 100;  
region.tSize.iHeight = 50;  

这里就引出一个疑问:展开后的匿名结构体arm_2d_location_t和arm_2d_size_t有什么作用呢?是不是很奇怪?
其实,我们本意是希望这个定义完全展开后,形如下面的代码(将匿名结构体也展开):

typedef struct arm_2d_region_t {  // tLocation 成员  union {  struct {  int16_t iX;                 //!< x in Cartesian coordinate system  int16_t iY;                 //!< y in Cartesian coordinate system  } tLocation;  struct {  int16_t iX;  int16_t iY;  };  };  // tSize 成员  union {  struct {  int16_t iWidth;             //!< width of an rectangular area  int16_t iHeight;            //!< height of an rectangular area  } tSize;  struct {  int16_t iWidth;  int16_t iHeight;  };  };  
} arm_2d_region_t;

那么,我们就可以方便的用如下两种方式来访问成员变量:

arm_2d_region_t region;  // 通过命名成员访问  
region.tLocation.iX = 10;  
region.tLocation.iY = 20;  
region.tSize.iWidth = 100;  
region.tSize.iHeight = 50;  // 通过匿名成员直接访问  
region.iX = 10;  
region.iY = 20;  
region.iWidth = 100;  
region.iHeight = 50;

是不是后面一种方式更简洁和直观?如此一来,写代码会清爽很多了。

要达到上述目的,让编译器将匿名结构体也展开,我们就需要使用-fms-extensions编译选项,明确指示编译器完成这个工作,对匿名结构体进行展开。

关于-fms-extensions
-fms-extensions 是 GCC(GNU Compiler Collection)和 Clang 编译器的一个编译选项,它用于启用对 Microsoft 编译器(MSVC)特定扩展的支持。这些扩展包括:

  • 允许 Microsoft 版本的匿名联合和结构体,这包括对 C11 匿名联合和结构体的支持,以及 Microsoft 特定的变体,如完全省略大括号成员列表,并将成员放置在父命名空间中,即使结构体/联合体有标识符。
  • 在 C++ 中,允许类成员与其类型同名(例如 using foo = int; struct A { foo foo; })。当禁用 ms-extensions 时,这种行为在 C 中是合法的;或者在没有给出 -pedantic 标志的 extern “C” 块中是合法的。对于这种情况的错误消息是 declaration of NAME changes meaning of NAME。
  • 在 C++ 中,允许隐式 int;任何会产生 ISO C++ forbids declaration of NAME with no type 诊断的情况现在都被允许,假设类型为 int。例如:const *p; 或 const f();。
  • 在 C++ 中,允许从命名一个非静态成员函数的 qualified-id 隐式转换为指向成员的指针。在 ISO C++ 中,执行该转换需要 & 运算符。
  • 在 C++ 中,如果 f(一个未限定的标识符)在该上下文中命名一个非重载的成员函数,则允许 &f 形成指向成员的指针。ISO C++ 要求使用类名进行明确的限定。

文章原创,欢迎转载,请注明出处,未经书面允许,不得用于商业用途。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86494.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86494.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/86494.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

默认构造函数

1、构造函数 一、什么是构造函数 c中有一种特殊的成员函数&#xff0c;他的名字和类名相同&#xff0c;没有返回值&#xff0c;而在创建对象时会自动执行&#xff0c;类中的数据成员的初始化往往通过构造函数来实现。完成类中数据成员的初始化&#xff0c;同时也是类中的成员…

带标签的 Docker 镜像打包为 tar 文件

现在还有人用docker吗 要将带标签的 Docker 镜像打包为 tar 文件&#xff0c;请使用 docker save 命令。以下是详细操作指南&#xff1a; 一、单镜像打包&#xff08;推荐方式&#xff09; # 基础格式 docker save -o [输出文件名].tar [镜像名]:[标签]# 示例&#xff1a;将…

基于GPS-RTK的履带吊车跑偏检测技术方案

基于GPS-RTK的履带吊车跑偏检测技术方案 1. 引言 1.1 项目背景 履带吊车作为重型工程机械&#xff0c;其行驶稳定性直接关系到作业安全和设备寿命。跑偏现象会导致履带异常磨损、转向系统过载&#xff0c;严重时可能引发侧翻事故。传统检测方法&#xff08;如激光测距或人工观…

勾正数据大数据开发面试题整理-20250625

最近面了家公司&#xff0c;想看看自己多年不准备面试&#xff0c;靠着老本能面试成啥样&#xff0c;算是试试水吧&#xff0c;一面过了&#xff0c;二面有个算法题没答出来&#xff0c;整体答得状态也不太好&#xff0c;应该是没过。 一面 先来说说一面吧&#xff0c;一面是…

基于中国香港会计准则差异,中国企业在香港推广ERP(SAP、Oracle)系统需要注意的细节

核心在于&#xff1a;ERP通常按单一会计准则设计主数据架构&#xff0c;但跨国企业需要同时满足两地报表要求。 用户常见的场景包括&#xff1a; 1 科目体系能否同时承载CAS的专项储备和HKFRS的禁止计提&#xff1f; 2 资产模块如何兼容不同的减值转回规则&#xff1f; 3 关联…

【编译原理】期末复习知识总结

目录 题型 总结 编译五大组成部分 编译与解释方式区别&#xff1f; 前端&#xff0c;后端&#xff0c;Why&#xff1f; 概念 推导、归约 短语、简单短语、句柄 文法 分类 正则文法&#xff08;3型&#xff09; NFA、DFA、最小化 自上而下语法分析&#xff08;推导…

【软考高级系统架构论文】论微服务架构及其应用

论文真题 论微服务架构及其应用近年来,随着互联网行业的迅猛发展,公司或组织业务的不断扩张,需求的快速变化以及用户量的不断增加,传统的单块(Monolithic) 软件架构面临着越来越多的挑战,已逐渐无法适应互联网时代对软件的要求。在这一背景下,微服务架构模式(Microservi…

【人工智能】RAG分块

在RAG&#xff08;检索增强生成&#xff09;系统中&#xff0c;文档分块&#xff08;Chunking&#xff09;是决定系统性能的核心环节&#xff0c;直接影响检索精度和生成质量。分块需平衡语义完整性、检索效率和上下文保留三大目标。 一、分块的核心标准 1.1 分块基础知识​ …

能耗管理新革命:物联网实现能源高效利用

在全球能源危机与 “双碳” 目标的双重压力下&#xff0c;企业与社会对能耗管理的重视程度达到前所未有的高度。然而&#xff0c;传统能耗管理方式存在数据采集滞后、分析维度单一、节能措施粗放等问题&#xff0c;无法满足精细化管理需求。物联网技术凭借其强大的数据感知、传…

基于CMS的黄道吉日万年历源码(自适应)

本模板采用帝国cms7.5版UTF-8制作&#xff1b; 适用站点&#xff1a;时间查询、时差计算、万年历、黄道吉日查询、假期查询、节气表等&#xff1b; 源码优势&#xff1a;代码精简&#xff0c;利于SEO、UI大气精简&#xff0c;搜索引擎收录高&#xff1b; 全站伪静态无需刷新生成…

如何构建个人AIagent

构建个人AI Agent是一个结合技术实现和场景设计的系统工程&#xff0c;以下是分步骤的详细指南&#xff0c;涵盖从需求定义到部署落地的全流程&#xff1a; ​一、明确Agent定位&#xff08;关键第一步&#xff09;​​ ​角色定义矩阵​ 类型典型场景技术复杂度示例信息处理Ag…

lutris登录不进去

日志 Cannot create Vulkan instance.This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU thatdoes not support Vulkan.ERROR at /home/abuild/rpmbuild/BUILD/vulkan-tools-1.4.313-build/Vulkan-Tools-vulkan-sdk-1.…

缓存与加速技术实践-NoSQL之Redis配置与优化

目录 #1.1关系数据库与非关系型数据库 1.1.1关心型数据库 1.1.2非关系型数据库 1.1.3非关系型数据库产生背景 #2.1redis简介 2.1.1redis安装部署 2.1.2配置参数 #3.1redis命令工具 3.1.1redis-cli命令行工具 3.1.2redis-benchmark测试工具 #4.1redis数据库常用命令 4.1.1ke…

走近科学IT版:FreeBSD系统下ThinkPad键盘突然按不出b、n、/和空格键了!

走近科学IT版&#xff1a;FreeBSD系统下ThinkPad键盘突然按不出b和n键了&#xff01; 很慌&#xff0c;以为键盘坏了&#xff0c;在控制台无法按出b和n&#xff0c;但是在浏览器里&#xff0c;可以按出来。 重启机器&#xff0c;结果在浏览器里也按不出来了.... 按Ctrl空格&a…

聚铭网络入选嘶吼《中国网络安全细分领域产品名录》“云平台安全管理”与“态势感知”双领域TOP10

近日&#xff0c;在嘶吼安全产业研究院发布的《中国网络安全细分领域产品名录》中&#xff0c;聚铭网络凭借其核心产品——聚铭云端安全管家与聚铭安全态势感知与管控系统&#xff0c;分别入选“云平台安全管理”与“态势感知”两大关键细分领域TOP10榜单&#xff0c;充分展现了…

DEYOLO 全面复现,将双增强跨模态目标检测网络 DEYOLO 融合到 YOLOFuse 框架

模型架构模态精度 P召回率 RmAP50mAP50-95模型大小(MB)计算量(GFLOPs)yolov8n (baseline)RGB0.8880.8290.8910.5006.28.1yolo-fuse-中期特征融合RGBIR0.9510.8810.9470.6012.613.2yolo-fuse-早期特征融合RGBIR0.9500.8960.9550.6235.26.7yolo-fuse-决策级融合RGBIR0.9560.9050.…

python基于Django+mysql实现的图书管理系统【完整源码+数据库】

摘要 随着信息技术与教育现代化的深度融合&#xff0c;图书管理系统的智能化与自动化成为提升资源利用效率的关键需求。本文基于Python语言&#xff0c;采用Django框架与MySQL数据库设计并实现了一套功能完备的图书管理系统&#xff0c;旨在通过信息化手段优化图书借阅流程、强…

论软件设计方法及其应用

20250427-作 题目 软件设计&#xff08;Software Design&#xff0c;SD)根据软件需求规格说明书设计软件系统的整体结构、划分功能模块、确定每个模块的实现算法以及程序流程等&#xff0c;形成软件的具体设计方案。软件设计把许多事物和问题按不同的层次和角度进行抽象&…

QT 自定义ComboBox,实现下拉框文本颜色设置

最近在做项目中遇到需求&#xff0c;在下拉框中&#xff0c;文本需要设置不同的颜色&#xff0c;遂网上了解了一番后&#xff0c;得出以下代码&#xff0c;可以完美实现效果&#xff0c;现分享出来&#xff01; 1.实现效果 2.自定义类 colorcombobox.h #ifndef COLORCOMBOBOX…

【时间戳】

在编程竞赛和高效数据处理场景中&#xff0c;时间戳技巧是一种极其高效的标记方法&#xff0c;常用于避免频繁清空数组或 map&#xff0c;提高算法运行效率。本文将从定义、应用场景、模板代码、技巧细节等方面系统整理时间戳的使用方式。 一、时间戳技巧是什么&#xff1f; 时…