免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: rollin7
打印 上一主题 下一主题

近期上cu的一点感慨  关闭 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-08-27 14:15 |只看该作者
原帖由 OwnWaterloo 于 2009-8-27 13:03 发表
看到lz在另外一贴中的留言:



如果你连这个都不能理解, 恕我直言……


这6、7年的时间, 十几万行的代码, 如果你能多思考一下, 而不是只为coding而code——上面那个应该很容易理解。


所以我 ...

老实说,这个我也不明白,能否讲解一下?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
22 [报告]
发表于 2009-08-27 14:38 |只看该作者

回复 #21 epegasus 的帖子

简单的说, 就是尽可能减少不必要的依赖。

如果某库(L)的头文件中给出struct 的定义, 那么客户代码(C1)可能会依赖于fields的名字于类型。
这样, L如果想改动struct 的定义, C1的代码就不得不重写。

即使通过文档来限制(通常, 这不太可靠,C++private就是提供一种语言机制来保障这一点)C1对fields的名字的取用, 依然有一个隐含的依赖排除不了:
struct S s; // 这里, 将依赖S的大小。

如果L想改变S, 就要考虑大小、 对齐等问题, 否则还是会破坏C1的代码,造成C1重写或重编译。


如果不给出定义, C1只能依赖于这么一个名字:
struct S* s;

在特定平台上, 指针的大小、对齐几乎是不会改变的。
所以通过不完全类型的指针, 就能最大程度的减少耦合。
无论L打算如何改变S的定义, C1的代码都不需要重新编译, 仅需要重新链接。 如果是动态链接, 仅需要替换.dll的文件。



不完全类型会使用动态存储的分配, 从而降低效率。
通过效率损失换取低耦合是否值得, 就是一个权衡问题了。

论坛徽章:
0
23 [报告]
发表于 2009-08-27 14:47 |只看该作者
原帖由 OwnWaterloo 于 2009-8-27 14:38 发表
简单的说, 就是尽可能减少不必要的依赖。

如果某库(L)的头文件中给出struct 的定义, 那么客户代码(C1)可能会依赖于fields的名字于类型。
这样, L如果想改动struct 的定义, C1的代码就不得不重写。
...

C1无须关心struct S的大小和定义,那它还要struct S*这样的东西,做什么,完全可以剔除,不是吗?如果不同的struct S*只是为了代表不同的实体,那甚至无须struct S出现在C1中了,任何一种标号都能拿来做区分.

论坛徽章:
0
24 [报告]
发表于 2009-08-27 15:05 |只看该作者
原帖由 ddkkd 于 2009-8-27 10:53 发表

股票+内幕=生活物质源泉
工作只当生活调料



内幕

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
25 [报告]
发表于 2009-08-27 15:14 |只看该作者

回复 #23 epegasus 的帖子

原帖由 epegasus 于 2009-8-27 14:47 发表
C1无须关心struct S的大小和定义,那它还要struct S*这样的东西,做什么,完全可以剔除,不是吗?如果不同的struct S*只是为了代表不同的实体,那甚至无须struct S出现在C1中了,任何一种标号都能拿来做区分.


思维相当敏锐嘛~~~

确实, 不使用struct S;也是可以的, 比如使用uintptr_t, void*。
struct S; 是利用语言的静态类型检测机制来减少一些错误。


举个uintptr_t的例子:
int fd = open( ... );
++fd; // ???  语言不阻止你做这个事情
write(fd, ... ); // 不幸

这就是使用uintptr_t 来标识一个对象的不足: 提供过多
如果只是用于标识一个对象, 算术操作通常是没有意义的, 应尽可能的不提供这个机制。


那么使用void*?
void* 可以避免客户代码对所指对象使用算术操作(ISO C, gcc扩展除外), 以及解引用操作—— 这些操作通常没有意义。

已经是一种不错的方案。 并且相对于uintptr_t, 还有一个可移植性优势:
语言保证任何对象的地址, 都可以保存在void* 对象中, 并且可以原封不动的转换回原来的指针。
int 做不到这点。 而uintptr_t、intptr_t 在c99中是optional的。



相对于void* , 提供一个struct S是有一些好处的。
void* 有另外一些好处, 这里就不说了……


假设:
void* t1_new(void);
void   t1_op(void* t1,int);
void   t1_delete(void* t1);

void* t2_new(void);
void   t2_op(void* t2, double);
void   t2_delete(void* t2);

void* o1 = t1_new();
void* o2 = t2_new();
t1_op(o1, 1212 ); // 正确的用法, ok
t1_op(o2, 1212.0); // 错误的用法, 语言无法检测
t2_op(o2, 326.0); // 正确的用法, ok
t2_op(o1, 1212); // 错误的用法, 语言无法检测

t1_delete(o2); // 都是错误的用法
t2_delete(o1); // 语言无法检测


如果换作:
typedef struct t1 t1;
t1*  t1_new(void);
void t1_op(t1* o, int);
void t1_delete(t1* o);

typedef struct t2 t2;
t2*  t2_new(void);
void t2_op(t2* o, double);
void t2_delete(t2* o);

上面的所有错误用法, 都能在编译时检测出来

论坛徽章:
0
26 [报告]
发表于 2009-08-27 15:56 |只看该作者
精辟.

论坛徽章:
0
27 [报告]
发表于 2009-08-27 16:10 |只看该作者
http://blog.chinaunix.net/u/24478/showart_385589.html
我的,不过是我刚毕业的时候写的,呵呵。
对有工作经验,不合适了。。。

论坛徽章:
0
28 [报告]
发表于 2009-08-27 17:20 |只看该作者
原帖由 yylogo 于 2009-8-26 22:30 发表
到哪里找学习项目?

很多,根据一些书的流程,一些实例的书后面都会有个比较大的项目

论坛徽章:
0
29 [报告]
发表于 2009-08-27 17:22 |只看该作者
原帖由 OwnWaterloo 于 2009-8-27 12:54 发表
c interfaces and implements


请问有这本书的英文原版么?我只找到中文翻译版的,如果能提供英文原版,将非常感谢

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
30 [报告]
发表于 2009-08-27 17:26 |只看该作者

回复 #29 lz_fine 的帖子

我没有英文版的……  这是实话

即使有, 你也不能这么随便要呀~~~
就在这几天就有个判3年罚100w的鸡, 我可不想作猴~~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP