C语言面向对象编程(四):面向接口编程

C++中如何进行面向接口编程和依赖注入? C++中如何进行面向接口编程和依赖注入 阅读详情

Java 中有 interface 关键字,C++ 中有抽象类或纯虚类可以与 interface 比拟,C 语言中也可以实现类似的特性。

    在面试 Java 程序员时我经常问的一个问题是:接口和抽象类有什么区别。

    很多编程书籍也经常说要面向接口编程,我的理解是,接口强制派生类必须实现基类(接口)定义的契约,而抽象类则允许实现继承从而导致派生类可以不实现(重写)基类(接口)定义的契约。通常这不是问题,但在有一些特定的情况,看起来不那么合适。

    比如定义一个 Shape 基类,其中定义一个 draw() 方法,给一个什么都不做的默认实现(通常是空函数体),这实际没有任何意义。

    再比如基类改变某个方法的实现,而派生类采用实现继承并没有重写这个方法,此时可能会导致一些奇怪的问题。以鸟为例,基类为 Bird ,我们可能会定义一个 fly() 方法,一个 walk() 方法,因为有的人认为鸟既可以走又可以飞。开始时我们在 walk() 的实现里作了假定,认为双脚交叉前进才是 walk ,可是后来发现有些鸟是双脚一齐蹦的,不会交叉前进。这个时候怎么办?基类 Bird 的 walk() 方法是否要修改、如何修改?

    在 C++ 中,没有接口关键字 interface ,同时为了代码复用,经常采用实现继承。在 C 语言中,我们前面几篇文章讨论了封装、隐藏、继承、虚函数、多态等概念,虽然都可以实现,但使用起来总不如自带这些特性的语言(如 C++ 、Java )等得心应手。一旦你采用我们前面描述的方法来进行面向对象编程,就会发现,在 C 语言中正确的维护类层次是一件非常繁琐、容易出错的事情,而且要比面向对象的语言多写很多代码(这很容易理解,面向对象语言自带轮子,而 C 要自己造轮子,每实现一个类都要造一遍)。但有一点,当我们使用 C 语言作面向对象编程时,比 C++ 有明显的优势,那就是接口。

    接口强制派生类实现,这点在 C 中很容易做到。而且我们在编程中,实际上多数时候也不需要那么多的继承层次,一个接口类作为基类,一个实现类继承接口类,这基本就够了。在 C 语言中采用这种方式,可以不考虑析构函数、超过 3 层继承的上下类型转换、虚函数调用回溯、虚函数表装配等等问题,我们所要做的,就是实现基类接口,通过基类指针,就只能操作继承层次中最底层的那个类的对象;而基类接口,天生就是不能实例化的(其实是实例化了没办法使用,因为结构体的函数指针没人给它赋值)。

    一个示例如下:

 

 
  1. struct base_interface {

  2. void (*func1)(struct base_interface* b);

  3. void (*func2)(struct base_interface* b);

  4. int (*func_3)(struct base_interface* b, char * arg);

  5. };

  6.  
  7. struct derived {

  8. struct base_interface bi;

  9. int x;

  10. char ch;

  11. char *name;

  12. };


    上面是头文件,derived 结构体通过包含 base_interface 类型的成员 bi 来达到继承的效果;而 base_interface 无法实例化,我们没有提供相应的构造函数,也没有提供与 func_1 , func_2 等函数指针对应的实现,即便有人 malloc 了一个 base_interface ,也无法使用。

 

    derived 类可以提供一个构造函数 new_derived ,同时在实现文件中提供 func_1 , func_2 ,func_3 的实现并将函数地址赋值给 bi 的成员,从而完成 derived 类的装配,实现 base_interface 定义的契约。

    示例实现如下:

 

 
  1. static void _derived_func_1(struct base_interface *bi)

  2. {

  3. struct derived * d = (struct derived*)bi;

  4. d->x *= 2;

  5. printf("d->name = %s\n", d->name);

  6. }

  7.  
  8. /* _derived_func_2 impl */

  9. /* _derived_func_3 impl */

  10.  
  11. struct derived *new_derived()

  12. {

  13. struct derived *d = malloc(sizeof(struct derived));

  14. d->bi.func_1 = _derived_func_1;

  15. d->bi.func_2 = _derived_func_2;

  16. d->bi.func_3 = _derived_func_3;

  17. d->x = 0;

  18. d->ch = 'a';

  19. d->name = NULL;

  20.  
  21. return d;

  22. }


    我们可以这么使用 base_interface 接口:

 

 

 
  1. void do_something(struct base_interface *bi)

  2. {

  3. bi->func_1(bi);

  4. }

  5.  
  6. int main(int argc, char **argv)

  7. {

  8. struct derived * d = new_derived();

  9. do_something((struct base_interface*)d);

  10.  
  11. return 0;

  12. }


    上面的代码中 do_something 函数完全按照接口编程,而 bi 可以实际指向任意一个实现了 base_interface 接口的类的实例,在一定程序上达到多态的效果,花费的代价相当小,却可以让我们的程序提高可扩展性,降低耦合。

 

    这种简单的方法也是我在自己的项目中使用的方法,效果不错。

    好啦,C 语言面向对象编程系列的基础性介绍就告一段落,下面是前几篇的链接,有兴趣的可以回头看看:

 

    接下来我会提供几个实作的例子,包括基本的数据结构,如单链表、树,还有一个 http server 的例子。

单片机C语言 -- 基于结构体的面向对象编程技巧 感谢阅读本文,在接下来很长的一段时间里,我将陆续分享项目实战经验。从电源、单片机、晶体管、驱动电路、显示电路、有线通讯、无线通信、传感器、原理图设计、PCB设计、软件设计、上位机等,给新手综合学习的平台,给老司机交流的平台。所有文章来源于项目实战,属于原创。 阅读说明: 1、Keil4 C51工程网址: https://yunpan.360.cn/surl_yrNkQSrCKyc 2、需要一定的C... 阅读详情

相关推荐

【C语言开源库】lw_oopc:轻量级的C语言面向对象编程框架

/ Move行为INTERFACE宏用于定义接口, 其成员(方法)均是函数指针类型. 然后, 我们分析Animal, 它应该是抽象类还是接口呢?// 动物的昵称(假设小于128个字符)int age;// 动物的年龄// 设置动物的昵称// 设置动物的年龄// 动物打招呼// 动物都会吃(抽象方法,由子类实现)// 动物都会呼吸(抽象方法,由子类实现)// 初始化昵称和年龄// 继承Animal抽象类// 实现IMoveable接口// 初始化昵称和年龄CLASS(Dog)

2401_89191942的博客 1458

C++面向接口编程具体指南

C# / JAVA中面向接口编程相对简单一些,特别是JAVA,更是如此,整个类库很多都是基于接口和设计模式搞出来的。 由于这些开发语言都具备内存GC机制,所以很多情况下不必关心创建出来的对象的销毁,而C++不同,new/delete的配对曾经搞得众多C++程序员焦头烂额。 好,重归主题,C++面向接口编程需要哪些必备知识和工具呢? 必备知识:               1,

zhougaomin_007的专栏 801

C语言的面向对象编程

通过上述的探讨,我们发现虽然C语言本身不支持面向对象编程,但我们依然可以通过结构体、函数指针和设计模式等技术模拟面向对象的特性。在实际开发中,采用面向对象的编程方法能够帮助我们更好地组织代码,提高代码的复用性和可维护性。尽管C语言的面向对象编程不是标准和普遍的做法,但在资源受限的环境(例如嵌入式系统)中,这种方式尤其有效。而且,许多系统和库都建立在C语言之上,理解如何在C中实现面向对象编程,可以帮助开发者更好地利用这些底层的技术。

2501_90199816的博客 813

C语言面向对象编程之四:面向接口编程

Java 中有 interface 关键字,C++ 中有抽象类或纯虚类可以与 interface 比拟,C 语言中也可以实现类似的特性。     在面试 Java 程序员时我经常问的一个问题是:接口和抽象类有什么区别。     很多编程书籍也经常说要面向接口编程,我的理解是,接口强制派生类必须实现基类(接口)定义的契约,而抽象类则允许实现继承从而导致派生类可以不实现(重写)基类(接口)

CoolBreeze的博客 528

C++中的接口编程与多态

通过使用抽象类或纯虚函数,我们可以定义一个通用的接口,然后由派生类提供具体的实现。这样做的好处是,它将代码的依赖性从具体的实现中解耦,提高了代码的灵活性和可维护性。当我们使用基类的指针或引用调用虚函数时,实际调用的是派生类的重写函数。通过多态,我们可以在运行时动态地确定要调用的函数,这为代码的扩展性和灵活性提供了很大的好处。多态是面向对象编程中的一个重要概念,它允许我们使用基类的指针或引用来调用派生类的方法。在主函数中,我们使用基类的指针指向派生类的对象,并调用它们的。函数即可,而无需修改现有的代码。

HackVibe的博客 184

面向接口的C++编程技术研究

结合C++开发工程实践,分析了目前C++开发所面临的问题,包括C++缺少二进制级标准导致的可移植性问题,和C++头文件不能完全隐藏实现部分而导致的封装性问题。分析了目前C++开发的2种通知机制的问题,包括使用虚函数继承实现接收通知导致的不符合常识的问题,以及使用组件类与客户类紧耦合导致的独立性差的问题。针对以上问题,结合目前主流的面向接口的编程技术,给出了在C++下的一种实现。

C 语言实现面向对象编程

C 语言实现面向对象编程 1、引言 面向对象编程(OOP)并不是一种特定的语言或者工具,它只是一种设计方法、设计思想。它表现出来的三个最基本的特性就是封装、继承与多态。很多面向对象的编程语言已经包含这三个特性了,例如 Smalltalk、C++、Java。但是你也可以用几乎所有的编程语言来实现面向对象编程,例如 ANSI-C。要记住,面向对象是一种思想,一种方法,不要太拘泥于编程语言。...

onlyshi的专栏 6万+

Mamba-ST实战:用状态空间模型实现艺术风格迁移的5个关键步骤

本文详细介绍了如何使用Mamba-ST状态空间模型实现高效的艺术风格迁移,涵盖环境配置、数据预处理、模型架构、训练策略和推理优化等5个关键步骤。Mamba-ST基于SSM(状态空间模型)构建,在保持生成质量的同时显著降低计算复杂度,为风格迁移领域提供了新的解决方案。

weixin_29163581的博客 354

c语言实现面向对象编程

c语言的面向对象框架(以RT-Thread软件包rt-robot为例) 概述   有一种说法是c语言是一门面向过程的语言,其实这种说法是比较浅显的,面向对象是一种编程设计思想,并不是各个编程语言的属性差异。在语法上,C语言支持的oop(面向对象)机制比较薄弱,但完全可以使用c语言写出面向对象的程序,只不过很多细节没有语法支持,需要编程人自己去实现。实际上编程实现机制的方式也并不只有提高工作量和门槛的弊端,它可以是更加灵活的。   这里使用的实例是一个c版本的面向对象框架,是根据RT-Thread 的rt-r

AntigravityC的博客 9287

流媒体弱网优化之路(NACK)——纯NACK方案的优化探索

流媒体学习之路(NACK)——纯NACK方案的最高性能 文章目录流媒体学习之路(NACK)——纯NACK方案的最高性能一、NACK简介二、Nack的理解2.1 一种补救策略2.2 什么时候要?2.3 要多少?2.4 怎么要?三、计算分析3.1 rtt强相关3.2 补包次数计算3.3 Nack的定时发送3.4 nack重传限制四、实验   近期在针对纯丢包场景做一些简单的探索实验,一个让我困扰的问题就是:不使用FEC而只是通过纯NACK进行补偿,到底能在实验环境下抵抗多少的丢包呢?每一次丢包补偿的最大时长

qw225967的博客 1万+

KiCad插件安装太慢?试试华秋版,再手把手教你装这5个实用插件

本文介绍了KiCad华秋发行版如何解决插件安装慢的问题,并详细推荐了5个实用插件及其安装方法。华秋版优化了国内用户的下载速度,预装了常用扩展包,包括BOM生成器、3D模型增强工具等,显著提升PCB设计效率。

weixin_29184075的博客 547

c语言如何实现面向对象编程

一、简介 C语言是面向过程的一门语言,C++是面向对象,这个特性早已深入人心。但是嵌入式底层以及大型操作系统等却都是用C开发的。如果只用面向过程去开发这类大型软件,肯定行不通。 因此,C语言也可以用面向对象的思维去开发。例如现在的STM32的HAL库就在向着这个趋势进发。 二、 C语言实现封装 大部分使用 C 语言进行开发的工程师,在接触更高级的编程语言之前...

qq_27726651的博客 4932

Trae 在代码审查场景的 3 大差异化能力:对比 Claude Code、Cursor 与 Codex 实测

揭示代码审查的核心矛盾是上下文断层而非找 Bug,介绍 Trae 通过跨文件符号追踪、意图-实现对齐校验、增量变更影响图谱生成三件事实现上下文校准,并对比其与 Claude Code、Cursor、Codex 在多模块 Java 项目中的实际审查差异

weixin_42525482的博客 151

C语言--面向对象编程之多态

系列文章目录 C语言–面向对象编程之封装 C语言–面向对象编程之继承 文章目录系列文章目录前言一、多态是什么?二、使用步骤1.引入库2.读入数据总结 – 前言 C语言实现面向对象编程的第三篇,在前面两篇里面我们已经讨论了C语言实现面向对象的封装与继承,这篇我们了解,面向对象的最后一个特性,多态,顺便了解一下C++中的虚指针与虚表。 一、多态是什么? 多态指的是能够根据对象的不同类型调用同一个接口,实现不同的功能。在C++中有一个叫做重载的功能,作用类似,比如下面的函数。 看例子: /*函数重载*/ in

weixin_46185705的博客 5232

【OpenClaw从入门到精通】第60篇:多智能体协同实战——用“龙虾”搭建你的数字员工团队(2026企业版)

2026年AI Agent企业落地的核心趋势,正从“单Agent单兵作战”转向“多智能体协同组网”。本文以全球开发者先锋大会“百虾大战”真实案例为蓝本,深度拆解OpenClaw多智能体协同的技术内核——三层解耦架构(模型层-技能层-网关层),系统搭建包含项目经理、架构师、执行者、质量把关者的4大核心Agent团队。通过三种主流协作架构对比、全链路配置代码实操、故障自愈实战演练,结合电商新品上架虚拟场景全流程演示,解决企业多Agent部署中的权限隔离、任务协同、运维自治三大核心痛点。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 767

第二节_PySide6项目创建流程介绍、手把手教学打包EXE可执行文件

本文详细介绍了如何使用PySide6创建一个带UI界面的Python程序,并将其打包成exe可执行文件。首先,通过Pycharm创建项目,并使用PySide6-Designer工具设计UI界面,将生成的ui文件转换为Python代码。接着,编写主程序,加载UI界面并实现功能,如加载图片、设置图标等。最后,通过资源文件管理图片资源,并确保UI界面的更新能同步到主程序中。整个过程涵盖了项目创建、UI设计、代码编写及资源管理,适合初学者学习如何将Python程序打包为可执行文件。

su桥木的博客 2554

C语言--面向对象编程之封装

文章目录前言一、面向对象基本概念什么是对象?对象与类面向对象的编程方式二、C语言实现面向对象面向对象的三大特征面向对象之封装简介代码实现2.读入数据总结 前言 面向对象是一种思维方式,基本上用什么语言都是可以实现的。C语言的编程方式一般是面向过程的,但是也是可以实现面向对象的。对象是什么?什么又是面向对象?面向对象的三大特性又怎么实现,且听我细细道来。 一、面向对象基本概念 什么是对象? 此对象非彼对象,虽然有时候此对象又可以是你脑袋中的对象,那让我们从我们误解的对象开始了解吧,虽然我没有,但是用一下自

weixin_46185705的博客 4874

大厂校招:星宸科技嵌入式面试及参考答案(5万字长文)

当一个新的硬件设备被插入系统时,内核会发送一个设备事件通知 udev,udev 会根据设备的属性和规则,为该设备创建一个合适的设备文件。通过去除不必要的驱动程序、禁用不需要的功能、选择合适的内核配置选项、优化内核编译选项和定制内核模块等方法,可以减小内核的大小和复杂性,提高系统的性能和稳定性。上半部通常是在中断关闭的情况下执行的,以确保中断处理的原子性。处理碎片化内存是内存管理中的一个重要问题,可以采用内存压缩、内存池管理、伙伴系统、首次适应算法和最佳适应算法等方法来减少内存碎片的产生,提高内存的利用率。

大模型大数据攻城狮的专栏 2927

C语言实现面向对象编程

GOF的《设计模式》一书的副标题叫做“可复用面向对象软件的基础”,从标题就能看出面向对象是设计模式基本思想。由于C语言并不是面向对象的语言,C语言没有直接提供封装、继承、组合、多态等面向对象的功能,但C语言有struct和函数指针。我们可以用struct中的数据和函数指针,以此来模拟对象和类的行为。 所以在正式开始设计模式前,先看看如何用C语言实现面向对象编程。 本章针对面向对象的封装、继承、组合、多态给出C语言的实现方法。 1 封装 封装是指对象仅暴露必要的对外接口(这里指public方法)来和其它

lbaihao的专栏 5329

VTK-9.5.0 1D2D3DWidget实现灰度图+深度图+3D点云显示(可轻松集成到自己的项目)

VTK1D2D3DWidget是一个基于Qt和VTK开发的3D点云可视化工具,支持RGB和深度点云数据的显示与处理。主要功能包括点云加载、可视化、保存为PLY格式文件,以及背景颜色、点间隔、坐标轴显示等参数的自定义设置。该工具采用模块化设计,核心组件包括主窗口管理类、VTK渲染组件和自定义鼠标交互样式,依赖Qt5+和VTK9.5.0库实现跨平台支持。项目提供完整的源码和构建指南,适用于点云数据的快速展示与分析。

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 385

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

嵌入式C语言自我修养:C语言的面向对象编程思想

⭐关联知识点:C和C++的区别。

_ 2874

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

如何在C语言里实现“面向对象编程”

有人认为面向对象是C++/Java这种高级语言的专利,实际不是这样,面向对象作为一种设计方法,是不限制语言的。只能说,用C++/Java这种语法来实现面向对象会更容易、更自然一些。 在本节中,就展示如何在C语言中实现面向对象编程,这是一件吃力的工作。写这些的目的有两个: ① 更好的掌握C++中的class的概念。学习了本章,就知道C程序员的无耐,就知道为什么要发明一个class的概念、为什么要

阿发你好 7203

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

上一篇: C语言面向对象编程(三):虚函数与多态
下一篇: C语言面向对象编程(五):单链表实现
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值