c语言中如何使用面向对象编程,如何使用C语言的面向对象

我们都知道,C++才是面向对象的语言,但是C语言是否能使用面向对象的功能?

(1)继承性

typedef struct _parent

{

int data_parent;

}Parent;

typedef struct _Child

{

struct _parent parent;

int data_child;

}Child;

在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。

(2)封装性

class的类成员默认情况下都是private,而struct的成员都是public(不能改变),所以如何让C语言实现封装的功能呢?答案就是函数指针;这在内核中得到了广泛的应用;

struct _Data;

typedef  void (*process)(struct _Data* pData);

typedef struct _Data

{

int value;

process pProcess;

}Data;

封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的。这样,我们就可以通过简单的一个结构指针访问到所有的数据,遍历所有的函数。封装性,这是类拥有的属性,当然也是数据结构体拥有的属性。

(3)多态性

在C++中,多态通常都是使用虚函数来实现的,但是C语言中并没有虚函数,如何实现重载呢?

答案也显而易见,也是函数指针的扩展,以下面例子为例:

#include

#include

//虚函数表结构

struct base_vtbl

{

void(*dance)(void *);

void(*jump)(void *);

};

//基类

struct base

{

/*virtual table*/

struct base_vtbl *vptr;

};

void base_dance(void *this)

{

printf("base dance\n");

}

void base_jump(void *this)

{

printf("base jump\n");

}

/* global vtable for base */

struct base_vtbl base_table =

{

base_dance,

base_jump

};

//基类的构造函数

struct base * new_base()

{

struct base *temp = (struct base *)malloc(sizeof(struct base));

temp->vptr = &base_table;

return temp;

}

//派生类

struct derived1

{

struct base super;

/*derived members */

int high;

};

void derived1_dance(void * this)

{

/*implementation of derived1's dance function */

printf("derived1 dance\n");

}

void derived1_jump(void * this)

{

/*implementation of derived1's jump function */

struct derived1* temp = (struct derived1 *)this;

printf("derived1 jump:%d\n", temp->high);

}

/*global vtable for derived1 */

struct base_vtbl derived1_table =

{

(void(*)(void *))&derived1_dance,

(void(*)(void *))&derived1_jump

};

//派生类的构造函数

struct derived1 * new_derived1(int h)

{

struct derived1 * temp= (struct derived1 *)malloc(sizeof(struct derived1));

temp->super.vptr = &derived1_table;

temp->high = h;

return temp;

}

int main(void)

{

struct base * bas = new_base();

//这里调用的是基类的成员函数

bas->vptr->dance((void *)bas);

bas->vptr->jump((void *)bas);

struct derived1 * child = new_derived1(100);

//基类指针指向派生类

bas  = (struct base *)child;

//这里调用的其实是派生类的成员函数

bas->vptr->dance((void *)bas);

bas->vptr->jump((void *)bas);

return 0;

}

综上所述,可以实现C语言的面向对象功能;

0b1331709591d260c1c78e86d0c51c18.png

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

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

相关文章

LeetCode 112路径总和-简单

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root [5,4,8,11,…

ASP.NET MVC升级到ASP.NET Core MVC踩坑小结

写在前面ASP.NET Core是微软新推出的支持跨平台、高性能、开源的开发框架,它的优势不必多说,因为已经说得太多了。当然,现在依然有着数量庞大的系统运行于.NET Framework上,由于有大量的Break Changes,很多项目项目团队…

用函数求C15的值C语言,南开19春学期(1503、1509、1603、1609、1703)《C语言程序设计》在线作业-1辅导资料.docx...

南开19春学期(1503、1509、1603、1609、1703)《C语言程序设计》在线作业-1辅导资料.docx 南开19春学期(1503、1509、1603、1609、1703)C语言程序设计在线作业-11、D 2、B 3、C 4、A 5、D 一、单选题共40题,80分1、以下对一维整型数组 a 的正确说明是 Aint a10 ;Bint…

LeetCode 563二叉树的坡度-简单

给定一个二叉树,计算 整个树 的坡度 。 一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。 整个树…

CIO/CTO都应该掌握和了解的EA(企业架构)

我们已进入数字化技术推动的第四次工业革命,是以工业互联网建设为标志。单纯从IT的视角管理信息化系统让许多企业深陷管理困境,解决问题也是按下葫芦浮起瓢。实际上,IT的服务对象是企业的战略、组织、管理、流程等一系列的要素,因…

扛并发主力军,引入应用层缓存

1.背景缓存的使用一定是今后开发中100%会用到的技术,尤其是Redis相关的问题,如果面试官不问我我几个缓存相关的问题,那我觉得我可能是去了个假的互联网公司。这里考虑到有些初学者刚刚出校园或者自学中,准许我多费口舌介绍下关于缓…

LeetCode 783二叉搜索树节点最小距离-简单

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 示例 1: 输入:root [4,2,6,1,3] 输出:1 示例 2: 输入:root [1,0,48,null,null,12,49] 输出:1 提示&…

使用 VMware + win10 + vs2019 从零搭建双机内核调试环境

我在前面的文章——《使用 VMware win10 VirtualKD windbg 从零搭建双机内核调试环境》分享了使用 windbg 进行双机内核调试的环境搭建的步骤。有小伙伴儿留言说:在使用 vs 进行双机内核调试的时候,总是连不上。希望能发一篇使用 vs 进行双机内核调试…

C#中的9个“黑魔法”与“骚操作”

C#中的9个“黑魔法”与“骚操作”我们知道 C#是非常先进的语言,因为是它很有远见的“语法糖”。这些“语法糖”有时过于好用,导致有人觉得它是 C#编译器写死的东西,没有道理可讲的——有点像“黑魔法”。那么我们可以看看 C#这些高级语言功能…

LeetCode 872叶子相似的树-简单

请考虑一棵二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个 叶值序列 。 举个例子,如上图所示,给定一棵叶值序列为 (6, 7, 4, 9, 8) 的树。 如果有两棵二叉树的叶值序列是相同,那么我们就认为它们是 叶相似 的。 …

.NET Core开发实战(第35课:MediatR:让领域事件处理更加优雅)--学习笔记

35 | MediatR:让领域事件处理更加优雅核心对象IMediatorINotificationINotificationHandler这两个与之前的 Request 的行为是不一样的,接下来看一下代码internal class MyEvent : INotification {public string EventName { get; set; } }internal class…

LeetCode 559N叉树的最大深度-简单

给定一个 N 叉树,找到其最大深度。 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。 N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。 示例 1: 输入:root [1,null,3,…

android 5.0状态栏下载地址,Android沉浸式状态栏(5.0以上系统)

Android沉浸式状态栏(5.0以上系统)沉浸式状态栏可以分为两种:1.直接给状态栏设置颜色 (如下图:)这里写图片描述java代码形式:if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {Window window activity.getWindow();window.addFlags(WindowManager.LayoutParams…

解析“60k”大佬的19道C#面试题(下)

解析“60k”大佬的19道C#面试题(下)在上篇中,我解析了前 10 道题目,本篇我将尝试解析后面剩下的所有题目。解析“60k”大佬的19道C#面试题(上)这些题目确实不怎么经常使用,因此在后文中&#xf…

android 卡顿代码定位,Android 性能优化实例:通过 TraceView 定位卡顿问题

8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?背景项目中使用了鸿洋大神的TreeView树状结构控件, 但是由于在主线程中使用了注解/反射来定位节点, 内容一多就有点卡顿。因此通过android …

DotNetCore三大Redis客户端对比和使用心得

前言稍微复杂一点的互联网项目,技术选型都会涉及Redis,.NetCore的生态越发完善,支持.NetCore的Redis客户端越来越多,下面三款常见的Redis客户端,相信大家平时或多或少用到一些,结合三款客户端的使用经历&am…

android elevation 白色,Android Elevation

简介:在Android API21,新添加了一个属性:android:elevation,用以在xml定义View的深度(高度),也即z方向的值。除了elevation之外,类似于已有的translationX、translationY,也相对应地新增了一个t…

(译)创建.NET Core多租户应用程序-租户解析

介绍本系列博客文章探讨了如何在ASP.NET Core Web应用程序中实现多租户。这里有很多代码段,因此您可以按照自己的示例应用程序进行操作。在此过程的最后,没有对应的NuGet程序包,但这是一个很好的学习和练习。它涉及到框架的一些“核心”部分。…

【要闻】Kubernetes无用论诞生、Elasticsearch 7.6.2 发布

导读:本期要闻包含OpenStack网络如何给组织带来好处、Portworx CEO分享的如何让Kubernetes跑得快还不出错的秘籍等精彩内容。大数据要闻Elasticsearch 7.6.2 发布,分布式搜索和数据分析引擎Elasticsearch 7.6.2 发布了,Elasticsearch 是一个分…

玩转控件:对Dev中GridControl控件的封装和扩展

清明节清明时节雨纷纷路上行人欲断魂借问酒家何处有牧童遥指杏花村又是一年清明节至,细雨绵绵犹如泪光,树叶随风摆动....转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一样,摇摇欲坠。裁员的裁…