C语言面向对象编程(二):继承详解

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

在 C 语言面向对象编程(一)里说到继承,这里再详细说一下。

    C++ 中的继承,从派生类与基类的关系来看(出于对比 C 与 C++,只说公有继承):

 

  • 派生类内部可以直接使用基类的 public 、protected 成员(包括变量和函数)
  • 使用派生类的对象,可以像访问派生类自己的成员一样访问基类的成员
  •  对于被派生类覆盖的基类的非虚函数,在派生类中可以通过基类名和域作用符(::)来访问
  • 当使用基类指针调用虚函数时,会调用指针指向的实际对象实现的函数,如果该对象未重载该虚函数,则沿继承层次,逐级回溯,直到找到一个实现

    上面的几个特点,我们在 C 语言中能否全部实现呢?我觉得可以实现类似的特性,但在使用方法上会有些区别。后面我们一个一个来说,在此之前呢,先说继承的基本实现。

 

    先看 C 语言中通过“包含”模拟实现继承的简单代码框架:

 

 
  1. struct base{

  2. int a;

  3. };

  4.  
  5. struct derived{

  6. struct base parent;

  7. int b;

  8. };

  9.  
  10. struct derived_2{

  11. struct derived parent;

  12. int b;

  13. };


    上面的示例只有数据成员,函数成员其实是个指针,可以看作数据成员。 C 中的 struct 没有访问控制,默认都是公有访问(与 java 不同)。

 

    下面是带成员函数的结构体:

 

 
  1. struct base {

  2. int a;

  3. void (*func1)(struct base *_this);

  4. };

  5.  
  6. struct derived {

  7. struct base parent;

  8. int b;

  9. void (*func2)(struct derived* _this;

  10. };


    为了像 C++ 中一样通过类实例来访问成员函数,必须将结构体内的函数指针的第一个参数定义为自身的指针,在调用时传入函数指针所属的结构体实例。这是因为 C 语言中不存在像 C++ 中那样的 this 指针,如果我们不显式地通过参数提供,那么在函数内部就无法访问结构体实例的其它成员。

 

    下面是在 c 文件中实现的函数:

 

 
  1. static void base_func1(struct base *_this)

  2. {

  3. printf("this is base::func1\n");

  4. }

  5. static void derived_func2(struct derived *_this)

  6. {

  7. printf("this is derived::func2\n");

  8. }


    C++ 的 new 操作符会调用构造函数,对类实例进行初始化。 C 语言中只有 malloc 函数族来分配内存块,我们没有机会来自动初始化结构体的成员,只能自己增加一个函数。如下面这样(略去头文件中的声明语句):

 

 

 
  1. struct base * new_base()

  2. {

  3. struct base * b = malloc(sizeof(struct base));

  4. b->a = 0;

  5. b->func1 = base_func1;

  6. return b;

  7. }


    好的,构造函数有了。通过 new_base() 调用返回的结构体指针,已经可以像类实例一样使用了:

 

 

 
  1. struct base * b1 = new_base();

  2. b1->func1(b1);


    到这里我们已经知道如何在 C 语言中实现一个基本的“类”了。接下来一一来看前面提到的几点。

 

   第一点,派生类内部可以直接使用基类的 public 、protected 成员(包括变量和函数)。具体到上面的例子,我们可以在 derived_func2 中访问基类 base 的成员 a 和 func1 ,没有任何问题,只不过是显式通过 derived 的第一个成员 parent 来访问:

 

 
  1. static void derived_func2(struct derived *_this)

  2. {

  3. printf("this is derived::func2, base::a = %d\n", _this->parent.a);

  4. _this->parent.func1(&_this->parent);

  5. }

 

 

    第二点,使用派生类的对象,可以像访问派生类自己的成员一样访问基类的成员。这个有点变化,还是只能通过派生类实例的第一个成员 parent 来访问基类的成员(通过指针强制转换的话可以直接访问)。代码如下:

 

 
  1. struct derived d;

  2. printf("base::a = %d\n",d.parent.a);

  3.  
  4. struct derived *p = new_derived();

  5. ((struct base *)p)->func1(p);

 

    第三点,对于被派生类覆盖的基类的非虚函数,在派生类中可以通过基类名和域作用符(::)来访问。其实通过前两点,我们已经熟悉了在 C 中访问“基类”成员的方法,总是要通过“派生类”包含的放在结构体第一个位置的基类类型的成员变量来访问。所以在 C 中,严格来讲,实际上不存在覆盖这种情况。即便定义了完全一样的函数指针,也没有关系,因为“包含”这种方式,已经从根本上分割了“基类”和“派生类”的成员,它们不在一个街区,不会冲突。

    下面是一个所谓覆盖的例子:

 

 
  1. struct base{

  2. int a;

  3. int (*func)(struct base * b);

  4. };

  5.  
  6. struct derived {

  7. struct base b;

  8. int (*func)(struct derived *d);

  9. };

  10.  
  11. /* usage */

  12. struct derived * d = new_derived();

  13. d->func(d);

  14. d->b.func((struct base*)d);

    如上面的代码所示,不存在名字覆盖问题。

 

 

    第四点,虚函数。虚函数是 C++ 里面最有意义的一个特性,是多态的基础,要想讲明白比较困难,我们接下来专门写一篇文章讲述如何在 C 中实现类似虚函数的效果,实现多态。

 

    回顾一下:

 

 

Win11+Ubuntu18.04+Ubuntu20.04三系统安装与卸载 以下情况均为个人情况:1.插入启动 U 盘后,登录时可以按F12(拯救者Y7000,不同电脑不同)进入BIOS,选择从启动盘启动。2.。3.5.在win基础上,安装第一个Ubuntu系统后,系统启动界面类似如下第一张图,Ubuntu不显示版本号。安装第二个Ubuntu系统后,系统启动界面如下第二张图,如果想更改启动项的名称,可自行查阅相关资料。 阅读详情

相关推荐

毕设案例|保安公司智慧管理系统的建设与开发方案

"保安公司智慧管理系统是一款专为保安行业设计的高效信息化解决方案,其核心功能涵盖了从人力资源管理到业务运营的各个方面。系统以Java作为开发语言,结合SpringMVC框架,确保了稳定性和可扩展性,而MySQL数据库则提供了强大的数据存储和处理能力。首先,系统允许用户设置各类保安,如门卫、巡逻员等,实现精细化分类管理。其次,保安信息管理模块包括详细的人事档案、资格证书、培训记录等,便于人员追踪和考核。部门和城市设置方便公司层级管理和异地项目管理。岗位设置与时间安排精确到分钟,确保排班科学合理。

muyu2980的专栏 935

C语言--面向对象编程之继承

系列文章目录 C语言实现面向对象编程的第二篇,在第一篇里面我们已经了解到了何为面向对象以及实现面向对象的第一大特性–封装,对于C来说,实现继承和多态要稍微麻烦一些。 C语言实现面向对象- - 封装 文章目录系列文章目录前言一、面向对象之继承何为继承?一个简单的Demo内存解析二、C++中继承内存分配demo代码简要分析三、总结 前言 这一篇将继续探讨用C实现面向对象编程之继承,用C来实现继承还是比较麻烦的,但是也能够实现继承,用C实现继承最好不要超过两级,不然实现继承与调用很繁琐。 一、面向对象之继承

weixin_46185705的博客 5191

anaconda的conda国内加速镜像源(pytorch 快速安装)

最近清华源不太好使了,所以推荐中科大镜像源,如下 1.还原原始通道 conda config --remove-key channels 2.

qq_41719643的博客 2万+

C语言学习笔记—C中的继承(方法1)

在此之前,我们一起学习了如何用C语言进行OOP,并了解了组合和聚合的概念。在这里我们继续讨论对象及其对应类之间的关系,涵盖继承和多态。 我们已经知道类之间可能存在的关系,C中继承和多态很大程度上依赖于前两章解释的理论基础。我们已经解释了组合和聚合关系,该文将继续讨论继承关系,以及一些其他主题。在上一篇笔记中,我们讨论了“拥有”关系,最终得到了组合和聚合关系。在该笔记中,我们将讨论“是”或“是一个”的关系,而继承关系是“是”的关系。

weixin_71643870的博客 2813

”COMSOL“竟然如此简单!我悟了!!

COMSOL Multiphysics具有强大的多物理场全耦合仿真分析功能、高效的计算性能,可以保证数值仿真的高度精确,已被广泛应用于各个学科领域,近年来运用COMSOL来解决电化学实际工程问题也越来越普遍。

C1012562281的博客 3447

让 AI 变聪明的 20 条指令:如何让大模型回答得更精准、更专业、更实事求是

让 AI 变聪明,本质上不是写几句神奇咒语,而是把你的任务表达得更清楚,把事实标准设得更严格,把输出格式规定得更明确,把不确定性管理得更认真,把历史对话利用得更充分。大模型的强项是语言生成、信息组织、模式归纳和方案扩展;弱项是事实核验、实时更新、责任判断和对模糊意图的准确猜测。好的指令,就是在用人的判断弥补模型的弱点,让模型把强项发挥在正确的地方。

Sumarua的博客 1476

【C++】C语言实现继承和多态

文章目录一、C语言实现继承二、C语言实现多态(1)静态多态(2)动态多态 一、C语言实现继承 原理:结构体组合类 //基类 typedef struct Base { //基类自身属性和方法 int b_val = 0; void show() { printf("b_val:%d\n", b_val); } }Base; typedef struct Son { //隐藏基类对象 Base base; //派生类自身属性和函数 int s_val = 10; void show()

xiaoxiaoguailou的博客 3027

面试问题总结——关于YOLO系列(三)

接着上篇的的YOLO系列面试问题总结,加油,冲! 三.YOLOv3 1.YOLOv3主干网络BackBone——Darknet-53网络结构(因为有53个卷积层) (原论文中Darknet53的尺寸是在图片分类训练集上训练的,所以输入的图像尺寸是256x256,而在YOLOv3中输入尺寸是416×416)   ①上图中,Top-1 Accuracy和Top-5 Accuracy是指什么呢?区别在哪呢?   我们知道ImageNet有大概1000个分类,而模型预测某张图片时,会给出1000个按概率从高.

boss-dog 1万+

用C语言实现C++继承与多态

用C语言实现C++继承与多态

qq704072809的博客 1458

AI赋能合同审查:构建租赁合同智能审核系统的全流程解析

在商业地产、设备租赁等场景中,合同审核效率直接影响业务流转速度。传统人工审核存在三大痛点:审核周期长(平均2-3个工作日)、合规风险高(条款遗漏率约15%)、人力成本居高不下。智能审核系统可将审核时间压缩至秒级,风险识别准确率提升至98%以上。

理论都是虚的,代码才是王道。 1356

Coverity本地增量C/C++代码检查(Linux)操作简介

Coverity 是一款精确的综合静态分析与应用安全测试 (SAST) 平台,它可以在编写代码时发现关键的缺陷和安全缺陷,防止它们变成安全漏洞、故障或维护缺陷。

1482

C 语言实现面向对象编程

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

onlyshi的专栏 6万+

自动驾驶模拟器:基于 Python + Carla,在家也能训练一个“L4 级”自动驾驶 AI 模型

市面上有很多模拟器(AirSim, LGSVL),但 Carla 是目前学术界和工业界最主流的选择。画质强:基于 UE4,光影、天气(下雨、夕阳)极其逼真,这对训练视觉模型至关重要。API 爽:完全使用 Python 控制,对 AI 工程师极度友好。资产多:内置各种车辆、行人、交通信号灯、城市地图。编写 Python 代码,让车自己在城市里跑,通过摄像头看到路况,自己决定怎么打方向盘。通过 Carla,我们把价值数百万的自动驾驶测试场搬进了电脑。

BUG猿的博客 267

C语言面向对象编程(一):封装与继承

C++ 语言中自带面向对象支持,如封装、继承、多态等面向对象的基本特征。 C 原本是面向过程的语言,自身没有内建这些特性,但我们还是可以利用 C 语言本身已有的特性来实现面向对象的一些基本特征。接下来我们就一一来细说封装、继承、多态、纯虚类等面向对象特性在 C 语言中如何实现,并且给出实例。

安晓辉生涯——聚焦程序员的职业规划与成长 6万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【C语言】C语言实现面向对象编程之继承

00. 目录 文章目录00. 目录01. 概述02. 利用结构体包含实现继承功能03. 利用私有指针实现继承功能04. 总结05. 附录 01. 概述 面向对象编程具有封装性、继承性、多态性三个基本特性。使用C语言可以实现基于对象的编程。在基于对象编程实现封装的基础之上,我们接下来实现面向对象编程中的继承部分功能。这种继承特性知识实现部分面向对象编程中继承功能。本博客中我们介绍两种方式的实现继承。第一种是利用数据结构的包含实现继承功能,第二种是利用私有指针实现继承功能,它们提供的接口是完全一致的,只是在实现

C/C++软件工程师、嵌入式软件工程师、物联网研发工程师、C/C++讲师、物联网讲师、嵌入式讲师、鸿蒙讲师---欢迎大家一起交流(私信添加博主微信) 2100

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

c语言实现面向对象编程

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

AntigravityC的博客 9287

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C语言面向对象编程:模拟实现封装、继承、多态

本文探讨了在C语言中模拟面向对象编程的三大特性:封装、继承和多态。通过结构体封装数据和函数指针,实现了类的基本结构;利用结构体嵌套模拟继承关系;借助函数指针实现多态行为。具体展示了String和Person类的封装实现、Student类的继承实现,以及Animal/Dog/Cat的多态示例。这种模拟方式虽然需要手动管理类型转换和函数绑定,但能有效提升C语言代码的模块化和扩展性,为理解面向对象底层机制提供了实践参考。

C语言、数据结构、单片机、嵌入式实时操作系统、C++ 学习路径记录 1209

C语言面向对象编程(二) 继承详解

C语言面向对象编程(二) 继承详解

jfdfhh的博客 246

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

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

_ 2874

C语言实现面向对象编程 : 封装、继承、多态

点击蓝字关注我们不知道有多少人去了解过语言的发展史,早期C语言的语法功能其实比较简单。随着应用需求和场景的变化,C语言的语法功能在不断升级变化。虽然我们的教材有这么一个结论:C语言是面向过程的语言,C++是面向对象的编程语言,但面向对象的概念是在C语言阶段就有了,而且应用到了很多地方,比如某些操作系统内核、通信协议等。面向对象编程,也就是大家说的OOP(Object Or...

轻松学C语言 1166

C语言实现面向对象编程

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

lbaihao的专栏 5329

C语言实现(封装、继承和多态)

1. 封装 这个最简单了,C语言中虽然没有类,但有struct。这可是个好东西。我们可以在一个struct中存入数据和函数指针,以此来模拟类行为。 typedef struct _Parent { int a; int b; void (*print)(struct _Parent *This); }Parent; 封装性的意义在于,函数和数据是绑在一起的,数据和数...

小麦大大博客 1万+

C++面向对象7——C继承与C++继承对比、C++继承详解

C语言通过结构体嵌套和函数指针可以部分模拟继承和多态,但存在类型安全、访问控制和代码复杂度等问题。C++则通过语言原生特性(类、继承、虚函数等)提供了更安全、更高效、更简洁的面向对象编程支持。若需兼容C代码或资源极度受限,使用C语言模拟若追求开发效率和代码可维护性,优先使用C++现代C++(如C++11及以后)通过智能指针、移动语义等特性进一步提升了继承机制的安全性和性能,减少了传统C++的一些痛点。特性描述关键语法public继承基类接口保持不变,实现"is-a"关系protected继承。

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值