如何使用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语言的面向对象功能;

来源:

https://www.cnblogs.com/linhaostudy/p/8448088.html

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

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

相关文章

t3软件怎么生成报表_临沂用友畅捷通T3财务通软件财税一体化

用友T3财税通针对财税一体化的发展趋势,在用友通上海财税专版的基础上,经过完善和提高。同时加入了税务核算功能、所得税汇算功能。 财税通财务软件的财税同步处理,可将事后税务处理的汇总涉税数据工作化整为零,分解到日常凭证填制…

每日干货丨C语言知识总结----循环结构

介绍循环结构可以看成是一个条件判断语句和一个向回 转向语句 的组合。另外,循环结构的三个要素:循环变量、 循环体 和循环终止条件. ,循环结构在 程序框图 中是利用判断框来表示,判断框内写上条件,两个出口分别对应着…

apache hadoop_使用Apache Hadoop计算PageRanks

apache hadoop目前,我正在接受Coursera的培训“ 挖掘海量数据集 ”。 我对MapReduce和Apache Hadoop感兴趣已有一段时间了,通过本课程,我希望对何时以及如何MapReduce可以帮助解决一些现实世界中的业务问题有更多的了解(我在这里介…

730阵列卡支持多大硬盘_凯捷月销破2万,配6座头等舱空间,到底有多舒服?试驾了才知道...

能够在还未上市的前一个月,就以预售的方式卖出超过2万台,上汽通用五菱在乘用车市场之中的号召力可见一斑。过去我们都将五菱视为商务领域的铭牌,包括宏光、荣光、之光等等家族,都在各自细分市场占据着最顶端位置。如今&#xff0c…

C语言循环嵌套

在C语言中,if-else、while、do-while、for 都可以相互嵌套。所谓嵌套(Nest),就是一条语句里面还有另一条语句,例如 for 里面还有 for,while 里面还有 while,或者 for 里面有 while,w…

rem 前端字体_web前端入门到实战:一次搞懂CSS字体单位:px、em、rem和%

对于绘图和印刷而言,“单位”相当重要,然而在网页排版里,单位也是同样具有重要性,在CSS3普及以来,更支持了一些方便好用的单位(px、em、rem…等),这篇文章将整理这些常用的CSS单位&a…

jvmti_JVMTI标记如何影响GC暂停

jvmti这篇文章分析了为什么Plumbr Agents在某些情况下以及如何延长GC暂停的时间。 对基本问题进行故障诊断揭示了有关在GC暂停期间如何处理JVMTI标记的有趣见解。 发现问题 我们的一位客户抱怨说,附加了Plumbr代理后,应用程序的响应速度明显降低。 通过…

C语言-使用goto语句从循环中跳出

实例代码// //实现功能:使用goto语句从循环中跳出 //#include "stdio.h"#define EXIT 0void show_Menu(){printf("菜单选项:\t");printf("1:显示\t");printf("2:添加\t");printf("3&#xff1a…

装饰器模式java_Java 8的装饰器模式

装饰器模式java在最近的一篇文章中,我描述了装饰器模式如何挽救了我的一天。 我给出了一个小代码段,其中包含创建装饰器的最简单方法,但承诺Java 8会有更好的方法。 这里是: 用Java 8装饰 HyperlinkListener listener this::ch…

C语言-反转字符串

实例代码// //实现功能&#xff1a;输入一个字符串&#xff0c;然后将该字符串反向输出 //#include "stdio.h" #include "string.h"#define N 50void convert_str(char str[N]);void convert_str(char str[N]){int j;char temp;for (int i 0; i < strl…

信捷步进指令的使用_步进电机驱动器的模式

步进电动机和步进电动机驱动器构成步进电机驱动系统。步进电动机驱动系统的性能&#xff0c;不但取决于步进电动机自身的性能&#xff0c;也取决于步进电动机驱动器的优劣。对步进电动机驱动器的研究几乎是与步进电动机的研究同步进行的。步进电机驱动器有三种基本的步进电机驱…

C语言灵魂篇|指针作为函数返回值

C语言允许函数的返回值是一个指针&#xff08;地址&#xff09;&#xff0c;我们将这样的函数称为指针函数。下面的例子定义了一个函数 strlong()&#xff0c;用来返回两个字符串中较长的一个&#xff1a;#include #includechar *strlong(char *str1, char *str2){ if(strlen(s…

css 样式尾部带感叹号是什么意思_CSS书写规范

推荐大家看看百度FEX前端团队和腾讯AlloyTeam前端团队的CSS代码规范。fex-team/styleguide​github.comCode Guide by AlloyTeam​alloyteam.github.io1. 样式属性顺序单个样式规则下的属性在书写时&#xff0c;应按功能进行分组&#xff0c;组之间需要有一个空行。同时要以Pos…

C语言精髓篇|函数的参数和返回值

如果把函数比喻成一台机器&#xff0c;那么参数就是原材料&#xff0c;返回值就是最终产品&#xff1b;从一定程度上讲&#xff0c;函数的作用就是根据不同的参数产生不同的返回值。函数的参数在函数定义中出现的参数可以看做是一个占位符&#xff0c;它没有数据&#xff0c;只…

oc引导win方法_[OC更新]机械革命X1/X6TIS标压测试版更新

加关注这种话银家怎么好意思说出口嘛更新机型机械革命X1 i5-7300hq机械革命X1 i7-7700hq机械革命X6tis i5-7300hq机械革命X6tis i7-7700hq更新内容基于OC0.6.2 MOD版本编译修复WIN下电脑被识别为MBP导致电竞中心打不开问题修复INTEL网卡在BIG SUR下不识别问题禁用secureboot mo…

java 打开gc日志_在运行时打开GC日志记录

java 打开gc日志总是有下一个JVM表现不佳。 而且&#xff0c;您内心深知&#xff0c;如果您只有少数启动选项可以公开一些有关正在发生的事情的信息&#xff0c;那么您可能就有机会真正修复该死的东西。 但是不&#xff0c;您需要的标志&#xff08; -XX&#xff1a; HeapDumpO…

C 和C语言条件运算符的区别

条件运算符&#xff08;conditional operator&#xff09;有时候也称为三元运算符&#xff08;ternary operator&#xff0c;或者trinary operator&#xff09;&#xff0c;因为它是唯一需要 3 个操作数的运算符&#xff1a;条件 ? 表达式1 : 表达式2条件运算操作会首先计算条…

C 运算符和语句总结

运算符&#xff1a; C 表达式中的左值和右值&#xff1a;当一个对象被用作左值时&#xff0c;用的是对象的身份&#xff08;内存中的位置&#xff09;。当作为右值时&#xff0c;用的是对象的值&#xff08;内容&#xff09;。或者说&#xff0c;lvalue:具有存贮性质的对象&…

# 遍历结构体_C#学习笔记05--枚举/结构体

一.枚举当变量的取值范围是固定的几个, 例如性别--男,女; 英雄类型 -- 法师, 刺客.战士, 射手等等. 这时就可以使用枚举类型, 会更加简洁方便.1.1.定义:访问修饰符 enum 枚举类型名 {成员1,成员2,成员3,... }public enum Days{Mon 1,Tue,Wed,Thu,Fri,Sat,Sun}enum: 是枚举的…

C语言中枚举enum的用法

本文举例说明C语言中enum枚举关键字的用法。用来同时定义多个常量利用enum定义月份的例子如下。#include enum week {Mon1,Tue,Wed,Thu,Fri,Sat,Sun}; int main() {printf("%d",Tue); return 0; }这样定义Mon的值为1之后&#xff0c;Tue的值就被默认定义为2&#…