免费注册 查看新帖 |

Chinaunix

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

问两个高级问题, [复制链接]

论坛徽章:
0
41 [报告]
发表于 2011-10-12 15:29 |只看该作者
回复 39# OwnWaterloo

好吧,你很伟光正。反正我说什么都是白说,都得挨批——只要你豪情来了。

实际上,针对这个问题来说,这个C++特性是没有必要的。

因为你还是必须用不同格式的输入参数,以便编译器选择正确的函数。如果你的设计无误的话,甚至连函数取名都没能节省,只是少打了几个字符而已。

比如,createImageByXXX 最终总是这样两步:
1、以XXX方式得到图片数据
2、用图片数据创建图片

这种问题在C里面,可以用链式调用解决:
createImage(loadImage(filename))          //从文件创建
createImage(clipImage(imageBuf, rect)) //从已有图片截取
createImage(xxImage(...))                   //以xx方式获得图片数据



至于完全等同于c++的重载形式,c并不能提供。当然你可以用可变参数函数/宏以及少量运行期性能代价来实现。

论坛徽章:
0
42 [报告]
发表于 2011-10-12 15:32 |只看该作者
别说什么不要脸的,如果用C你也只能这么办,小心打到自己的脸。
OwnWaterloo 发表于 2011-10-12 15:29


哎呦喂,真不容易,总算说了句人话。

既然C/C++都得这么办,你得瑟什么?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
43 [报告]
发表于 2011-10-12 15:36 |只看该作者
回复 41# 狗蛋

比较生成一个图片有以下几种方式,1> 根据路径名生成图片, 2> 从另一张图片中裁剪出一个图片, 3>根据像素数据生成一个图片>
creatImageByPath(), creatImageByBuffer(), creatImageByWhat ???
三月廿七 发表于 2011-10-11 13:21


我想你可能是想用一个createImage(...)来统一所有这些接口。
这样,输入路径,就去读磁盘文件;输入图片和区域信息,就去图片中截取数据并生成图片;输入XX,就用XX方法得到图片……

实际上,针对这个问题来说,这个C++特性是没有必要的。

因为你还是必须用不同格式的输入参数,以便编译器选择正确的函数。如果你的设计无误的话,甚至连函数取名都没能节省,只是少打了几个字符而已。

比如,createImageByXXX 最终总是这样两步:
1、以XXX方式得到图片数据
2、用图片数据创建图片

这种问题在C里面,可以用链式调用解决:
createImage(loadImage(filename))          //从文件创建
createImage(clipImage(imageBuf, rect)) //从已有图片截取
createImage(xxImage(...))                   //以xx方式获得图片数据

至于完全等同于c++的重载形式,c并不能提供。当然你可以用可变参数函数/宏以及少量运行期性能代价来实现。
狗蛋 发表于 2011-10-11 15:29


回复  狗蛋
你的方案 —— 引入这么多东西,我不觉得这很好维护,对C++没有抵触情绪的我来说这简直是糟糕透了 —— createImage倒是一个名字了。
但又多出loadFromXXX/YYY/ZZZ。
就好比有人问"如何求2的平方根",得到的回答是"我们先引入一个√记法,然后求2的平方根"。
也许你自己不觉得, 但在我看来就是这样 —— 绕了个圈子但没有解决实际问题
OwnWaterloo 发表于 2011-10-12 13:26

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
44 [报告]
发表于 2011-10-12 15:43 |只看该作者
哎呦喂,真不容易,总算说了句人话。
既然C/C++都得这么办,你得瑟什么?
狗蛋 发表于 2011-10-12 15:32


我该说你终于听懂了一句人话吗? 其他的人话还是没听懂吗?

1. C++可以提供完全适合lz需要的重载。
C你能办到吗? 你那套鬼画符算个啥?你又得瑟什么?

2. generic什么的我不想再提了, 我发现你的智商根本理解不了稍微有点深度的抽象。
C里面你能为任意类型编写一个sort算法吗? 能与template的效率匹敌吗? 你又得瑟什么?

3. 运行期决策的需求 —— 这是你自己提出来跑题的
C/C++都需要这么办, 所以我不觉得这有什么不要脸的。
你觉得这很不要脸, 那就只能自己扇自己了。
另外, 一个是编译器维护, 一个是人肉维护的区别, 你到底有没有看到? 还是故意装作看不见? 你还再得瑟什么?

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
45 [报告]
发表于 2011-10-12 15:51 |只看该作者
两位不要上火了,从两位的回复当中都可以看到是很有想法有能力的人,就某个问题有各自的看法是不希奇的,不用上升到互相指责的地步!

讨论问题,其实大家都是有自己的一套默认的前提条件的,如果这个不统一其实两位可能很难说到一起去。

狗蛋可能是由于LZ不希望使用C++,所以希望在这样的前提下以C尽可能的满足LZ的需求。

而OwnWaterloo是希望阐明使用C++和generic programing的优点,而希望LZ改用C++。

两位都是很有能力的人,希望能更多在技术角度上讨论,让大家都受益,感激不尽!

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
46 [报告]
发表于 2011-10-12 15:58 |只看该作者
在C++里,如果编译期参数即可确定,那么可以通过编译期代价来选择正确的调用;但这同样可以直接写函数名来代替。

这显然不提供任何额外功能,仅仅是方便了懒汉程序员罢了——所以,才叫它“语法糖”。
狗蛋 发表于 2011-10-12 15:05


哦,你不懒,去写汇编好吗? 何必要用C语言?
我与你的区别就在于能理解这语法糖同时也是一种抽象机制。

既然你能理解C对机器的抽象, 为什么不能理解重载对相同动作的抽象?

是,泛型我知道,03年我改写STL的内存池还用在实际的工程里,而且是化工厂的仪表监控控制台后台服务这种要害代码。

重载之于泛型的作用,我当然更知道。
最起码,没重载,就没add(T, T)。
这么核心的东西要不重要,那就真没什么重要了。

不过,现在谁和你说泛型了?谁要用C来模拟泛型了?
狗蛋 发表于 2011-10-12 15:05


提到范型而跑题是我不对。 但不提它无法很好说明重载不仅仅是语法糖,而是一种抽象机制 —— 这你自己也承认了。
而你提的运行期需求又是怎么回事? 谁跑题更严重?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
47 [报告]
发表于 2011-10-12 16:08 |只看该作者
狗蛋可能是由于LZ不希望使用C++,所以希望在这样的前提下以C尽可能的满足LZ的需求。
而OwnWaterloo是希望阐明使用C++和generic programing的优点,而希望LZ改用C++。
asuka2001 发表于 2011-10-12 15:51


1. 我也不希望lz用C++ —— 那是折磨他,你看他都那么不情愿了
2. 我认为要想在C语言里面实现完整的重载机制是不现实的 —— 这也是狗蛋的观点

其实我的目的在8楼与9楼就达到了 —— lz啊,你这两个问题都是伪问题,别纠结了。
这时候狗蛋在哪里???


之后狗蛋乱入,提出了一套什么什么的东西。
我就该直接点告诉他:这就是绕个圈子拉屎,脱了裤子放屁,别给lz带来莫名的希望了, 老老实实的createImageFromXXX/YYY/ZZZ 就好了。
谁知道说委婉了,以讨论的语气和他说反而还让他得瑟无比根本听不进去?

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
48 [报告]
发表于 2011-10-12 16:17 |只看该作者
回复 47# OwnWaterloo

希望在C中达到完整的C++里的效果,那恐怕只有把编译器重写下了:)即不现实也不必要的!

但是现实是有的时候不得不使用纯C来完成工作,比如某些古老的单片机不提供C++编译器,这个是程序员无法控制的事。

这个时候没有办法,也只能采用一些权益之计了。从这点上说,我认为狗蛋的方法还是有值得学习的地方的。所以希望两位不必互相指责,而在技术角度上取得共识,更能让大家学习到很多:)

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
49 [报告]
发表于 2011-10-12 16:31 |只看该作者
回复  狗蛋

我的回帖并不是特别针对image的例子,而是想表明:
1. 有些情况确实很适合用重载表达,而非 ...
OwnWaterloo 发表于 2011-10-12 13:26



    从这里开始,你们两个就已经谈岔了。狗蛋说的是,并不要模拟C++,用C自己的方式去解决问题。GP不一定能解决问题。GP也不一定就是解决方案,既然本就不打算用GP做事儿,那C没有GP的机制又有什么问题呢?

本质上,考虑GP实际上就是用C++的思维方式思考了。C语言的思维方式非常简单,lisp的思维方式你熟悉了吧?去掉了macro的lisp就和C很近了。C就是调用。编译器不帮你选择调用函数,要调用哪个函数自己决定。这样不好么?为什么非要GP不可?一个设计,就必须得GP么?

回到楼主的问题,很简单,我分C思维和C++思维回答:

1. C思维:头文件是用于导出全局符号和类型声明的。而.c文件是具体实现全局符号的。理想的.c文件是一堆static函数,加上一两个不带static标志的函数。这种情况下,.c文件是自洽的。传统的C项目是不会为了不同模块去分离目录的,因为每个.c文件都是一个独立实现某个功能的实体,分目录代表你狠心虚,你在潜意识里认为同一个目录的.c文件是有关联的,这种想法本质上就是错误的。每个.c文件都各干个事,不管看上去逻辑关系有多相近不同就是不同。你要做到,如果编译的时候漏掉了几个.c,唯一出现的错误只可能是链接错误。结论:C语言中,各个.c文件是没有任何逻辑关联的。

C++思维:C++和上述描述很相近,即.cpp文件之间是没有任何逻辑关联的。但是很遗憾的。因为有所谓的“富头文件”存在,.cpp文件之间客观地的确是会互相影响的。而事实上,对于大多数C++来说,.h文件已经不仅仅是接口了,他们更是实现的一部分(比如模板,比如inline函数),这时,一个理想的做法是将.h和.cpp放到一个文件夹,并在外部的include目录中,创建短小的.h文件,去include那个文件夹的.h文件。libc++、Qt都采用了这种方法。这种方法即保证了C++文件书写的自然性,也提供了类似C的一致性访问接口。清晰简单。结论:作为实现一部分的.h文件和.cpp放在一起,在外界创建proxy头文件指向实现中的公用头文件。


2. C思维:C的世界是没有重载的。你在思考重载,那你本质上就根本没用C思维去思考问题。C的世界里面,只有函数调用,跳转。一切都是你说明白了的。当你发现你必须要让编译器帮你做些事情的时候,要么就是你在写机械化的模块代码,要么就是你的思维绕了弯路。通常只有一种情况需要大量用到宏:你打算设计一套统一流程,但是因为局部数据或者效率的原因不得不放在一个地方实现(不允许用分离的.c文件),这种情况下可以用到很复杂的宏去实现。但在超过1W行代码的项目里面,有这样的情况是很危险的事情。结论:当你想到了重载,请调整你的思维。你并不需要这种特性。

C++思维:天生就有重载。掠过。

第二点其实没说明白。这里有很多设计上的经验衬底。没有经过良好项目的实战设计可能很难明白,而且面对这么抽象的一个话题也很难说到具体。这涉及到C语言项目设计方法学。总之,别因为讨厌C++而去用C,恨得越深爱的越深。你是在乎C++才讨厌他。你是恨铁不成钢才不愿意用它。别让C++牵绊你,C就是C,没有重载,很多事情反而可以做得更优雅。C复杂的函数表格可以让你在真的需要virtual的时候好好想想,还有没有别的方法。比之C++不费吹灰之力就能得到的能力而言。C语言的艰辛能让你去深入思考需求,让你不去为了耍酷装逼而做无用功。

如果决定用C,那就完全忘记C++的存在吧。用C的思维去写代码。你会发现很优雅。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
50 [报告]
发表于 2011-10-12 16:36 |只看该作者
回复 48# asuka2001

lz感到 createImageByXXX/YYY/ZZZ 很"别扭"(这词恰当么?) 。
但并没有说需要 createImageByRuntimeInfo(RuntimeInfo ... ) 。

假设lz没有后面一个需求, 我不觉得狗蛋的方法有什么值得学习的。
C语言里面老老实实的实现3个函数才符合C的风格。
别说什么不要模拟又做一套扇自己嘴巴的事情 —— 你是云风吗?

假设lz有后面一个需求, 至少对我来说没什么值得学习的。
别说什么谦不谦逊的。
那种不温不火最后双方都"保留自己观点(甚至还在心里默默将对方骂个狗血淋头)"的讨论在我看来才是浪费时间。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP