c语言错误封装,C语言实现的封装,继承,多态
提到面向对象编程,我们想到的就是封装、继承、多态,但是其实这几个特性并不是只有面向对象语言才能实现,面向过程的C语言也是可以支持实现这三个特性的,下面我们来具体看下
封装1
2
3
4// point.h
struct Point;
struct Point* makePoint(double x, double y);
double distance(struct Point *p1, struct Point *p2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// point.c
#include "point.h"
#include
#include
struct Point {
double x, y;
};
struct Point* makePoint(double x, double y){
struct Point* p = malloc(sizeof (struct Point));
p->x = x;
p->y = y;
return p;
}
double distance(struct Point* p1, struct Point* p2){
double dx = p1->x - p2->x;
double dy = p1->y - p2->y;
return sqrt(dx*dx + dy*dy);
}
这样使用point.h 的程序就不知道 Point 的内部结构,实现了数据的封装,外部只能使用声明的两个函数,如:
1
2
3
4
5
6
7
8
9// 使用 demo
#include
#include "point.h"
int main(){
struct Point* p1 = makePoint(5, 6);
struct Point* p2 = makePoint(6, 7);
printf("%lf",distance(p1, p2));
}
继承
接着上面的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include
#include
#include "point.h"
struct NamedPoint {
double x, y;
char* name;
};
struct NamedPoint* makeNamedPoint(double x, double y, char* name){
struct NamedPoint* p = malloc(sizeof(struct NamedPoint));
p->x = x;
p->y = y;
p->name = name;
return p;
}
int main(){
struct NamedPoint* p1 = makeNamedPoint(0, 0, "origin");
struct NamedPoint* p2 = makeNamedPoint(3, 4, "new");
// 本来接受的参数只能是 Point类型的指针,这里是把 NamedPoint的指针进行强转
printf("%lf",distance((struct Point*)p1, (struct Point*)p2));
}
这是能够进行强转调用,是因为 NamedPoint 结构体的前两个成员的顺序与 Point 结构体的完全一致,所以可以进行强转,这其实就可以算是一个单继承
多态
最后我们来看一下多态,这个C语言也是可以实现的,通过使用函数指针
先看一个简单的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include
#include
// 定义函数指针
typedef int (*myFunc)(int, int);
// 定义函数1
int add(int n, int m){
return n + m;
}
// 定义函数2
int substract(int n, int m){
return n - m;
}
int main(){
// 为函数指针使用不同的函数实现进行调用
myFunc f = &add;
printf("%d\n", f(1, 2));
f = &substract;
printf("%d\n", f(1, 2));
}
上面的例子如果大家感受还不太明显的话,接下来看一个 redis 源码中的使用
1
2
3
4
5
6
7
8
9// dict.h
typedef struct dictType {
uint64_t (*hashFunction)(const void *key);
void *(*keyDup)(void *privdata, const void *key);
void *(*valDup)(void *privdata, const void *obj);
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
void (*keyDestructor)(void *privdata, void *key);
void (*valDestructor)(void *privdata, void *obj);
} dictType;
上面这个结构中都是函数指针,可以类比为 Java 中的接口及对应函数声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46// uint64_t (*hashFunction)(const void *key) 实现函数
uint64_t dictSdsHash(const void *key) {
return dictGenHashFunction((unsigned char*)key, sdslen((char*)key));
}
// int (*keyCompare)(void *privdata, const void *key1, const void *key2) 实现函数
int dictSdsKeyCompare(void *privdata, const void *key1, const void *key2){
int l1,l2;
DICT_NOTUSED(privdata);
l1 = sdslen((sds)key1);
l2 = sdslen((sds)key2);
if (l1 != l2) return 0;
return memcmp(key1, key2, l1) == 0;
}
// ================= 具体的类型实现 =================
/* Set dictionary type. Keys are SDS strings, values are ot used. */
dictType setDictType = {
dictSdsHash, /* hash function */
NULL, /* key dup */
NULL, /* val dup */
dictSdsKeyCompare, /* key compare */
dictSdsDestructor, /* key destructor */
NULL /* val destructor */
};
/* Sorted sets hash (note: a skiplist is used in addition to the hash table) */
dictType zsetDictType = {
dictSdsHash, /* hash function */
NULL, /* key dup */
NULL, /* val dup */
dictSdsKeyCompare, /* key compare */
NULL, /* Note: SDS string shared & freed by skiplist */
NULL /* val destructor */
};
/* Db->dict, keys are sds strings, vals are Redis objects. */
dictType dbDictType = {
dictSdsHash, /* hash function */
NULL, /* key dup */
NULL, /* val dup */
dictSdsKeyCompare, /* key compare */
dictSdsDestructor, /* key destructor */
dictObjectDestructor /* val destructor */
};
这几个类型都可以类比看做上面的接口的具体实现类,每个类有自己对应的函数实现
所以不是使用了面向对象的语言,写出的代码就是面向对象的,而使用了面向过程的语言写出来的代码就不行,只不过面向对象的语言对面向对象提供了更好的支持,写起来更方便,更安全而已。代码质量的好坏不是仅仅靠使用了什么高级语言就可以的,要想提升代码质量还是需要我们去不断思考和实践的
c语言错误封装,C语言实现的封装,继承,多态相关推荐
- c语言错误c1021,c语言经典错误
C语言命语法错误大全 C语言命语法错误大全 fatalerrorC1004: unexpectedendoffilefound 未找到文件末尾(可能是括号匹配问题) fatalerrorC1021: ...
- c语言错误writing,C语言编译器的错误信息
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Not a valid expression format type 不合法的表达式格式 Not an allowed type 不允许使用的类型 Num ...
- c语言错误stray,C语言20条编程中遇到的错误提示(4页)-原创力文档
C语言20条编程中遇到的错误提示 代码: 编译器提示错误:error: 'else' without a previous 'if' 错误原因解读:'else'的前面没有匹配的'if' 代码: 编译器 ...
- c语言错误2015,C语言2015(回答).doc
C语言2015(回答) 一.单项选择题 1.以下不是C语言特点的是( B ). A)C语言简洁.紧凑 B) 能够编制出功能复杂的程序 C)C语言可以直接对硬件进行操作 D) C语言移植性好 2.以下不 ...
- c语言错误指导,c语言编程指导.pdf
高质量C++/C 编程指南 文件状态 文件标识: [ ] 草稿文件 当前版本: 1.0 [ √] 正式文件 作 者: 林锐 博士 [ ] 更改正式文件 完成日期: 2001 年7 月24 日 高质量C ...
- c语言错误re,c语言malloc之后再realloc的有关问题
C/C++ code#include #include #include "../Status.h" #define STACK_INIT_SIZE 5 //堆栈初始大小 #def ...
- c语言错误spawning,C语言一直出现Error spawning cl.exe的解决办法
这几天这个问题一直困扰着我,我考二级三|级时用过的VisualC++软件拷贝到别人电脑上后,一直出现这个问题.因为在准备计算机四级,我好久没用过这个软件了.开始我有点不相信,今天我验证了一下,结果如下 ...
- c语言错误c4047,c语言错误 apos;int apos; differs in levels of indirection from apos;int *apos;...
用数组编的多项式乘法,但是不会合并同类项 从同学那参考了合并的方法,但是有错误 比较着急!! 下面是程序 #include #define N 100 void multiply(int a[],in ...
- c语言错误c4430,C 语言 typedef 与 #define 比较
Alvin typedef 与 #define 的区别 1. 执行时间不同 关键字 typedef 在编译阶段有效,由于是在编译阶段,因此 typedef 有类型检查的功能. #define 则是宏定 ...
最新文章
- 【CTF】实验吧 奇怪的短信
- 点阵大屏语音感应时计——人体感应
- 机器人图形变变变_幼儿园大班数学活动《图形变变变》PPT课件教案下载 - 快思幼教网...
- 2012-02-14 貌似情人节
- UE4 身体部件换装实现
- atitit.二进制数据无损转字符串网络传输
- 计算机四级网络题型,全国计算机四级考试题型
- python数学实验与建模pdf_Python数学实验与建模(4)
- 产品读书《引爆点:如何引发流行》
- [leetcode 3sum】 三数之和问题 @python
- DLL load failed: %1 不是有效的 Win32 应用程序的解决办法
- EasyExcel导出设置表头字体样式和批注
- 磁珠和电感在解决EMI和EMC的不同应用
- 2023届深信服C++A卷笔试
- 读书百客:《宿新市徐公店》评赏
- 国际贸易术语解释通则(DES 目的港船上交货(……指定目的港))
- [LOJ2568][可并堆]APIO2016:烟花表演
- Java期末考试试题及参考答案(10)
- H264编解码SPS、PPS参数说明
- 3COM 交换机端口的监听配置 ZT
热门文章
- 求约瑟夫环问题最后胜利者的一般解法以及数学推导方法
- Vue脚手架搭建简单步骤
- MySQL知识树 集合操作
- BZOJ4428 : [Nwerc2015]Debugging调试
- PowerShell 笔记
- [bzoj1700]: [Usaco2007 Jan]Problem Solving 解题
- Windows Store 开发总结——文件操作
- 关于--在 System.Threading.ThreadAbortException 中第一次偶然出现的“mscorlib.dll”类型的异常(转)...
- Html前端基础(这些基础标签你必须知道!)
- Node.js下载安装及各种npm、cnpm、nvm、nrm配置(保姆式教程---提供全套安装包)---npm的安装与配置(2)