免费注册 查看新帖 |

Chinaunix

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

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

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

你也卖得一手好萌……

论坛徽章:
0
22 [报告]
发表于 2011-10-11 16:22 |只看该作者
回复 19# OwnWaterloo


    是的。但在C里面用途就有限的很了。

论坛徽章:
0
23 [报告]
发表于 2011-10-11 16:38 |只看该作者
本帖最后由 狗蛋 于 2011-10-11 16:50 编辑
能详细说说么? 特别是几乎无额外运行期开销? 几乎到什么程度?

如果是C++重载:
createImage(fil ...
OwnWaterloo 发表于 2011-10-11 16:16



    这个设计没有和C++比较的意思,也完全没有可比性。

我想我在前面已经说的够清楚了:永不模拟其它语言特性,尤其不模拟其它语言的语法糖;并且,模拟机制设计的再好,也比不上编译器的原生支持。

这里仅仅是一个举例,说明用C模拟重载机制的一个可行思路——如前所述,C中搞这个基本上没有意义——并且,证明在C中即便模拟,往往也不是简单模拟其它语言的内部机制就行,要切合实际设计自己的机制。

2、不要仿造其它语言的特性,仿制它们的功能。

很多人喜欢用C来模拟C++类,模拟它的继承、重载等等机制。

但必须记住,c不是c++。

硬要让它和c++表现类似的话,何不直接使用c++?至少比你用宏以及其它诘屈聱牙的变态语法模拟出来的那个四不像更稳定可靠(毕竟那么多人用那么多年了)、速度更快(多少人做了多少优化,而且还有编译器内置支持的优化)、语法更简洁易懂(用宏来模拟c++,怎么搞都是变态,怎么搞都没法杜绝所有不需要的副作用,哪里比得上编译器的关键字支持)

无论如何,用c来模拟c++,你只能得到一个比c++更坏无数倍的怪胎。

狗蛋 发表于 2011-10-11 11:04



至于运行期开销,其实就是个二维数组的存储空间和额外的一次二维数组寻址操作。维护当然也较麻烦,但我认为完全可以接受。

比如,IMAGE的metadata值为0x1,URL为0x2,那么transFun_URL_IMAGE就在函数指针数组里面[2][1]这个位置。

注册额外的类型转换函数可以用宏来执行,如: REG_TRANS(URL, IMAGE, loadImage)就会设定函数指针数组[2][1]这个位置内容为loadImage的地址。

当然,如果类数量非常大,还可以用稀疏表、hash表之类东西时间换空间;或者,在添加类型转换函数时,修改metadata的某些位来标记它们的位置(此时类/对象中存的应该是metadata的指针而不是ID);甚至,直接在类metadata中添加相关转换函数指针。


实际设计中,metadata可能要实现更多的额外功能,比如标识类层次之类。这些现在就不讨论了。


另外,如果真要粗暴模拟c++重载,我也不会搞的这么局限了:直接可变参数+metadata,c++看起来啥样俺就能搞成啥样。

不过,这样做,就的的确确是邯郸学步,不仅没把c++好的东西学到手,反而得爬着走路了。

论坛徽章:
0
24 [报告]
发表于 2011-10-11 21:05 |只看该作者
回复  三月廿七


    看不起C++就自己去写一个支持重载的C编译链接器去
x5miao 发表于 2011-10-11 00:41



    c不支持重载?难道我以前认识的重载是错的?老觉得重载是相同的名字不同的函数签名。
呃……你们平时说的重载是啥意思?重写?因为准备着应聘,到时候把你们说的“重载”会错意就不好玩了

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
25 [报告]
发表于 2011-10-12 09:15 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
26 [报告]
发表于 2011-10-12 10:16 |只看该作者
"以xxx方式得到图片数据"在C++里面还可以继续重载…… 比如:

createImage(imageDateFrom(filename) ...
OwnWaterloo 发表于 2011-10-11 16:07



    这个“继续重载”即便在C++中也仍然是——无意义。

当然,不是无意义——注意我上文特指的是哪种情况。


这东西和多态有个本质不同,那就是:这些函数的参数类型、个数都不一样。


类型不一样好解决,哪怕是在C语言里面,像我那个方案一样稍微付出点运行期代价即可;C++里面可以用模板函数,编译器会自动根据参数类型切换正确的函数,这在很多情况下可以不付出任何运行期代价。


不过,考虑这个循环:
foreach item in imageList
     item.loadImageData(/*URL or IMAGE_DATA*/)

假设参数类型是URL还是IMAGE_DATA甚至是IMAGE_DATA加上rect共两个参数,都是运行期才能知道的;那么即便是模板,要在这里根据参数是URL还是IMAGE_DATA切换合适的函数,也同样需要运行期代价吧(我没试过这样做,不知道模板究竟能否支持这样的变态做法)。


当然,你可以:
foreach item in imageList
     if (param is URL)
            item.loadImageData((URL)param) //强制转换为URL,迫使编译器选择正确的实现
     else if (param is IMAGE_DATA)
……

不过,与其强制类型转换,何不老老实实写:
foreach item in imageList
     if (param is URL)
            item.loadImageByURL(param)
     else if (param is IMAGE_DATA)
……
呢?

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
27 [报告]
发表于 2011-10-12 11:11 |只看该作者
直接把C++拿来当C用,不就好了吗?

论坛徽章:
0
28 [报告]
发表于 2011-10-12 11:17 |只看该作者
1> 假设有 math.h,  math.c, string.h, string.c
> 假设有 math.h,  math.c, string.h, string.c
是把 math.h,  math.c, string.h, string.c 放在一个文件夹合适呢? 还是分别放在 inc, src 文件夹合适呢??

2> 怎么样给 c 语言重载呢?
newPlayer1(), newPlayer2() 好恶心啊,三月廿七 发表于 2011-10-10 22:54


第二个问题,用OIOIC重载

论坛徽章:
0
29 [报告]
发表于 2011-10-12 12:13 |只看该作者
第二个问题,用OIOIC重载
OIOICpp 发表于 2011-10-12 11:17


请参见我 6 楼的回复...

论坛徽章:
0
30 [报告]
发表于 2011-10-12 12:20 |只看该作者
回复 29# 三月廿七


    OIOIC是C语言,不是C++,你不会连这个都不知道吧 {:3_182:}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP