作者icetofux ()
看板C_and_CPP
标题[问题] 纯C下的结构化跟函数指标问题
时间Tue Feb 19 23:12:27 2019
开发平台(Platform): (Ex: Win10, Linux, ...)
无
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
GCC
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
无
问题(Question):
在纯C(目前编译器有支援到C99)的环境下,我试着以下述方式进行资料封装:
void DoorOpen(void) {
// ...
}
typedef struct {
void (*open)(void);
void (*close)(void);
} CAR_DOOR;
CAR_DOOR car_door = {
.open=,DoorOpen
.close=NULL,
}
typedef struct {
CAR_DOOR* door;
CAR_ENGINE* engine;
} CAR;
CAR car = {
.door=&car_door,
.engine=NULL
};
使用时就以下面的方式操作
car.door.open();
car.engine.enable();
优点:
1.使用时感觉比较结构化。
2.如果有另外一个主结构叫home,只要把car跟home放在不同的档案(.h/.c),
DoorOpen这类函式只要宣告成static,命名就可以相同,不用为了取名字烦
恼,或是把函式名字拉得很长。
缺点:
1.写起来有够麻烦。
2.door、engine都必须宣告出来,其他结构的指标才能指向它。
3.如上面例子中,CAR_ENGINE结构或是CAR_DOOR下的close函式我还没想到要怎麽实现
前,如果只给NULL,不小心存取到会发生问题。
4.比起直接呼叫函式效率应该会差一些,不过在我的应用上这些差异可以忽略。
请问是不是有什麽方法可以改善克服这些缺点,或是有更好的做法写出较具维护性的
code呢?
谢谢大家。
喂入的资料(Input):
无
预期的正确结果(Expected Output):
无
错误结果(Wrong Output):
无
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
无
补充说明(Supplement):
无
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.250.44.253
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1550589149.A.813.html
※ 编辑: icetofux (111.250.44.253), 02/19/2019 23:13:14
※ 编辑: icetofux (111.250.44.253), 02/19/2019 23:14:12
1F:→ Lipraxde: 研究一下C语言的历史,然後改用C++ 02/20 00:19
2F:推 chuegou: 我好像有一篇是跟你有一样的困扰 你参考看看 02/20 00:31
4F:→ tjjh89017: 你CAR那边可以考虑不用CAR_DOOR*,而直接用CAR_DOOR 02/20 02:15
5F:→ tjjh89017: 然後再搭配一些init function或是init macro 02/20 02:15
6F:→ tjjh89017: 应该可以解决你的问题 02/20 02:15
7F:推 IhateOGC: 我会写init ,marco 几年後谁来维护 02/20 06:09
8F:推 IhateOGC: 手边十个bug还要花时间弄懂你写的 02/20 06:11
9F:→ IhateOGC: 对团队来说是地雷 02/20 06:11
10F:推 IhateOGC: 太多fuction根本不是问题,ide就解决了 02/20 06:13
11F:推 eye5002003: 比起物件导向的思维,函数式(FP)的作风更适合C 02/20 11:35
12F:→ eye5002003: 用C写OO只要一个结构配一堆函式就好了,想太多都是徒劳 02/20 11:38
13F:→ Lipraxde: 你在呼叫open, close ...的时候如果要指定哪个门或哪台 02/20 12:50
14F:→ Lipraxde: 科的门,最後还是要把指标传进去,C这样用真的会比较方 02/20 12:50
15F:→ Lipraxde: 便吗? 02/20 12:50
16F:→ loveme00835: 你先从 Abstract Data type (ADT) 去设计, 我发现很 02/20 13:55
17F:→ loveme00835: 多书在教人写扣的时候都忽略抽象化这个观念, 先提供 02/20 13:55
18F:→ loveme00835: 足够的抽象化, 其他封装什麽的都是在这个前提下去作 02/20 13:58
19F:→ loveme00835: 的, 方法各异. 简单的例子可以看 fopen/fclose 系列 02/20 13:59
20F:→ loveme00835: 的挡案操作 02/20 13:59
22F:推 Neisseria: Stroustrup 博士曾经有类似的困扰,他最後做了新语言 02/20 14:56
23F:→ Neisseria: 要不要考虑直接用他做的语言,还蛮多人用的 02/20 14:57
24F:→ Neisseria: 认真回,把结构当 this 指标,永远摆在函式第一个参数 02/20 14:59
25F:→ descent: 所以才有 c++, 其他人写的也是这样, 不会有更好的写法了 02/20 17:50
26F:→ descent: 你的 open 还没有把 door * 传进去 02/20 17:53
27F:→ descent: 加上後, 会更冗长 02/20 17:53
谢谢各位的建议,我收获良多,不过需要一些时间思考跟查资料,所以没针对各位提供
的方案即时回覆。
有一点要澄清一下,虽然我的OOP不是学得很深,但是只要情况允许C++绝对是我的首选。
只是因为程式运行的平台大多是MCU/MPU/DPS这类产品,大部分的平台开发环境只提供
C编译器,或是更多的场合是在维护或扩增老旧的C code专案功能,才会出现这种用C
去写这类结构的情境。
※ 编辑: icetofux (111.250.44.253), 02/20/2019 21:48:07
28F:→ Neisseria: 网路上找 C 语言 物件导向 有一些文章会展示手法 02/20 23:46
29F:→ Neisseria: 本来就不是语言内建的东西,用一些概念去写得像 OO 02/20 23:47