天行健 君子当自强而不息

C/C++之争


目前吵的很凶。

都说什么C++快不行了,可是游戏开发这种东西,还是非C++莫属,图形开发这块C++还是强项。我发现C#,JAVA之类的之所以能在企业级应用和快速开发方面占有优势,完全是因为别人已经帮你封装好了一套好用的API函数,而不是这些语言的语法机制本身提供了多少优点,而C++和C却不这么做,因为C/C++相信使用它的程序员完全有能力自己封装,没必要替他们封装。

对于C++提供的继承、模板等高级特性,应该谨慎使用,尽量做到继承的层次很少,各个类之间是组合关系,从而达成一种平板结构,以实现各个类之间最低的耦合度,降低维护和理解的成本。同时由于类隐藏了数据,又将特定的数据和函数绑定在了一起,这样就可以减少全局变量的使用,降低了由于大量使用全局变量所引发的风险。同时类的封装降低了各个函数之间通信的成本,减少了函数参数的个数,而通过多态这一特性可以更加有效地降低函数调用的参数个数。

C与C++通过良好的设计都可以架构一个优秀的框架,而C++通过面向对象这一特性(类、继承、多态等)可以更加有效的实现封装和信息隐藏,但架构不应该太复杂,继承层次不要过多,类和类应该尽量是一种平板组合关系。

我的观点是少一点语言之争,多学一点实用的技术,真正起决定作用的往往是对具体技术的掌握,比如Windows运行机制,Windows网络编程基础,API函数,3D数学基础,3D图形学基础,DirectX提供的具体接口和函数,游戏制作技术的熟悉,以及数据结构和算法等等,到最后用什么语言来实现其实是一个次要的问题了。至于架构好点差点倒不是最重要的,没有这些基础知识的积累,东西憋都憋不出来,更不要谈什么架构了。

附一些网友的观点:

我对 C 和 C++都很喜欢,但是更喜欢用 C,因为比较简单。C++也很好,只是许多特性都用不上,我喜欢用最简单的办法去解决实际的问题,并尽量保证其合理性。做设计应当以实际问题为出发点,作抽象是好的,但是任何事物都有适用范围,没有人能够写出完全通用的、普适的代码,用 C++ 也做不到。这类似于以不变应万变和随机应变之间的关系。C++程序员有时候太过执著于抽象设计,执著于通用库的设计,执著于可重用,执著于面向对象,以至于忘了设计的根本是为了解决实际问题,忘了除了面向对象的设计方法还有更多其他的设计方法,忘了设计的简洁,忘了设计是否容易被他人所理解,忘了除了重用,还有更多需要注意的地方。C++使人们在设计时,在面向对象、抽象和可重用上背上了太多包袱,以至于许多人沉溺其中,而没有更多的精力去做更多的事情。

以不变应万变是相对的,而随机应变则是绝对的。也就类似于静止是相对的,而运动与变化是绝对的,这样一个哲学道理。因此,从这个角度上将,修改或重写代码都是绝对会发生的。而我们尽力所要保证的重用性,其实都是相对的重用性。因此,有必要考虑,是否真的需要花费大量的精力,去保证这种相对的可重性。

我之所以要这样讲,是因为近几年,可重用性被强调得太多太过。以至于人们忘了自己真的需要做什么。

相对于代码的可重用性,我更加看重代码的可维护性和可扩展性。好的代码都是开放的,可维护,可扩展的。尽量保持扁平的层次结构,尽量使用基本的数据类型,尽量减少自定义的数据类型,使整个系统的设计更加容易被人所理解。

真正好的设计,都是开放的,简洁的,易于理解的。毕竟维护的最基本的条件,就是先要理解现有的代码。

而所谓的可重用性和抽象,都给以上目标的实现,带来了极大的障碍。因此需要根据实际需求,在各个方面取得平衡。否则,一切关于语言的争论都是毫无意义的。

一个系统,不管你设计得多么抽象,多么可重用,他总有适用的范围。而为了达到重用和抽象,所使用的技巧不管多么高明,如果它很难被理解的话也是毫无意义的。因为这个系统总有一天会走出他的适用范围,这个时候就需要修改和维护其代码。如果这个系统很难维护,那么,就算它当初的设计很高明,但也走到了生命的尽头,逃脱不了被重写的命运。



因此,从实际出发,分清主次,做自己真正该做的事情才是关键。感觉可重用和面向对象被强调得太过,以至于人们迷失了方向。

学习期。 c,简单,干练。简单到没什么好学的。有用的技能都是在实际运用中获得exp然后lvup的。可以这么说,初学者可以很快得掌握c,但是基本上却什么都不能做。立竿不能见影。这是c的简单干练所决定的,是必然的。 c++,复杂,强大。c++的这些特点已经无须论证。遍地开花的垃圾c++程序员用铁一般的事实说明了一切。针对于与c的比较,仍然来说说立竿见影的问题。我的观点是,虽然这一点c++做得比c好一些,但是仍然不能达到立竿见影的程度。结论,就这个阶段来说,不分胜负。

开发期。在任何软工项目都处于“硬件受限”的时代和环境下,c是毫无疑问的王者。(当然,如果你脑容量可堪负荷,请使用asm)但是在现在,情况分2种。第1种,我是一个独裁者。当我需要清楚地知道我的代码做了什么的时候,c->asm仍然是最适合的合作者。这种人多半是战斗在“硬件受限”的原始时代。Linus就处于这样一种时代,所以他不得不用c。不要告诉我linux可以跑在多么牛B的机器上,内存可以多么的大,这是p话,linux的 kernel必须不能用尽一切可以触及的资源,因为它只是一个承载其他东西的方舟,他必须委屈自己假装是在一个超级受限的环境下工作,把美味的梨子让出来给依赖着它的兄弟姐妹们。所以,kernel类的开发者毫无疑问是战斗在一个“硬件受限”的原始时代,c->asm是他们最好的合作者。 ps.游戏引擎也算半个“硬件受限”环境。虽然不需要承载如kernel般繁多的东西,但是引擎最终将被用来产生实作品,从设计者的角度出发,也必须在一定规模——没错,就是规模——上考虑到由这个引擎所生产出来的东西将要产生的负荷——这毫无疑问地成为了一个“受限”的环境。——但是尽管如此,c- >asm也不一定就是最优解,在我的观点来看,这是语言无关的——当然,目前可以做出的选择不多,就个人而言,我仍然选择了c++。第2种,我是一个追求高产的商人。在性能要求不太严苛的情况下,c就是一个渣。太多的东西需要自己去做,这意味着将会带来冗长的开发周期,这会导致成本的急剧增长,包括各种可量化的(人力物力财力)和不可量化的(团队稳固性团队士气)成本。因此,在这种环境下,c就是一个渣。c++毫无疑问比c做得好。但是,在这个领域里,c和目前的c++都已经失去了辉煌的宝座,新生代的高级语言都拥有给他们致命一击的实力。结论,从表面来看,仍然是不分胜负。但是c在这一阶段具有稳定、明确的应用领域,算是小胜吧。

运行期。仍然是分成2种情况,效率关键和效率不关键的。在避开其他环节的情况下,前者当然比后者更受欢迎。但是,运行期的效率直接与开发期的质量相关,因此运行期的事又是不可能和开发期完全隔开的。 “不管用什么样的语言,都可以写出糟糕的程序。”——这话也可以反过来说,“用任何一种语言,都可以写出优秀的程序。” 因此,在我眼中,这仍然是一个语言无关的问题。不要把失败的理由放在你无法控制的地方,优秀的进化者会改变自己适应环境。——这是我的观点,因此,我更希望自己能成为“用任何一种语言,都可以写出优秀的程序”这样一个开发者。我认为,每一个以成为优秀开发者为目标的程序员,都应该以这样一种精神为指导,虽然不一定要确实地做到,但是应该具备这样一种精神。用更容易理解的话来说,就是要做到手中有剑心中无剑(请注意这跟武侠小说上的说法是反的-_-!)结论,既然都语言无关了,当然没有胜负之说。

维护期。 OK,这实际上是一个软工项目中生命周期最长的阶段。这里涉及了很多东西,最主要的就是3个方面:调试、维护、复用。这三个议题每一项都可以大书特书再书还要书。既然是生命期中最长的一个阶段,因此c对c++的重量级攻击放在这里当然就会很有效果。在维护上的代价而言,结构过程化的c比抽象对象化的c++便宜太多了。这是“结构过程化”与“抽象对象化”的根本不同所造成的差别。用程序员们更能够理解的方式来说,c就像一个链表,要增减head很方便;而c++就像一个动态数组,要insert[0]或者remove[0]就要牵一发而动全身!但是,c真的就很好维护么?非也!一个疯狂使用#define的c程序,不会比一个滥用oo特性的c++程序更好调试和维护。因此,这仍然是与开发期工作的质量息息相关的。结论,好吧,我不得不说,在我眼中c和c++仍然不分胜负。

综上所述,c和c++在我眼中不分好坏,具有同等的地位。他们分别代表了两种不同的编程思想。 “结构过程化”的c带来的好处是赋予程序员更为强大的控制力,和维护期可以“断章取义”的灵活性——但是代价是更多你不得不亲历亲为的工作。 “抽象对象化”的c++带来的好处是更为贴近现实的思维要求,以及更具亲和力的“人机交互接口”——当然,代价是需要你练好足够的基本功来了解c++在背后到底做了些什么,以及在维护期和复用阶段你可能要面临的“抽筋”式的痛苦。

作为一个拥有美好愿望的程序员,我希望有一种语言,既能给我c的强大控制力和维护期的灵活性,又能给我c++的亲和力和强大的——好吧,我承认我比较喜欢template那种拐弯抹角的东西——脑力训练(—_,—),然后,又能轻易地满足KISS的原则——这将可以让我非常简单地找到高质量的合作者 ——毕竟怪物级的c/c++程序员不是像现在的本科生一样遍地都是。而且基于c/c++的灵活性——这里叫做不确定性更好——这一特征,每个怪物级的 c/c++程序员都有很大可能不能跟另一个怪物互相咬合他们脑袋里高速转动的齿轮——如果你非要那么做,这很可能会带给你更多的机会让你的项目走火入魔,甚至停摆,最后以自爆收场。

但是遗憾的是,目前这只能是一个美好的愿望而已,我不得不采取折中的办法来找一些代替品。因此,目前我的做法是,用c的规则来写c++的程序,略微地用一些可以被我完全控制的c++的特性(模板的编译期编程技术很赞,可以为运行期的效率和正确性带来很大的好处),最根本的出发点是建立在获得强大控制力和可预期的维护期工作量的目的之上的,当然,还有不能忽视的效率问题——我的目标是一个可扩展的游戏引擎。

胡言乱语了一堆也不知道说了些啥……最后做个总结性发言吧:c和c++都不是什么好东西,但是正如windows也不是什么好东西一样,我们却非得要用它们——至少在可以预见的一段不会算短的时期内。

另外,撇开c/c++的比较说点跑题的话。

c++目前确实处于一个相当尴尬的境地,高不成低不就,过于复杂庞大的身躯又成为了他能够被更熟练掌握的门槛。c++目前有两条路可走,一是朝c退过去,二是朝更高之处攀登。但是无论走哪一边,都是“强敌环视”,要想闯出一片新的天空,恐怕需要剑走偏锋了。至于是不是一定要偏着走,偏又要怎么个偏法,我也说不出个所以然来,且让我们拭目以待吧。而c,很可能将会止步于“硬件受限”的时代吧,然后在这个时代和环境下再一点一点地进化,最终与c++将来的终点完全分道扬镳。

个人以为,程序语言的发展以后将会明确地分出两个方向,一个是以c为代表的“底层亲和”的语言,它们的特点是将给于程序员最大的控制能力,让一切尽在程序员的掌握之中。另一个将是以不断发展的新兴高级语言为代表的方向,也可能是c++以后的方向,它们的特点是不断地将底层的东西从程序员的眼前隐藏起来,让程序员的门槛降得更低,充分地体现出KISS原则,并从而提高生产力和生产效率。

人类的知识累积将随着时间的流逝慢慢增长,如果没有一种有效的途径让后来者可以从更高的地方起步的话,光是学习就足以耗尽人的一生了。因此我认为,“隐藏底层的东西”,将成为今后应用软件技术发展的关键,说白了就是让程序员傻瓜化。



本是同根生, 相煎何太急. C/C++本来就是用来开发系统级应用的, 有何必强分彼此呢?

在程序开发中, 最重要的根本就不是语言,而是设计(在这点上面, Linus说得是对的).

之后的问题: 效率, 重用, 扩展等等问题都取决于你的设计和软件的要求. 这个并不存在绝对的标准. 说C++开发不好的兄弟们, 请考虑考虑, 如果你用C改写同样的软件, 你可以保证写出来的软件质量就一定好过用C++写的?

c/C++当然存在个自适用范围的情况, 一般认为C比较适合OS内核和迁入式的开发. 而C++一般不太适合在这两种环境下面. 这个原因是很多的, 其中很重要的一个原因是由于C++的OO特性会产生不必要的负载(其实, 如果软件设计得当的话,加上一个合适的编译器, 这个并不是很大的问题. 在这裡,就假定C++不适合这些领域). 但是做游戏领域呢? 图形介面领域呢? C++就非常合适(而C在这裡就显得麻烦了). 两种语言都有长处和不足.

C++由于提供了太多的内容(OO/模板/泛型...), 导致了大家有太多的选择, 结果在软件设计的地方错用了C++的特性, 导致了软件的各种问题(效率差, 不可扩展等等). 这个是设计的问题, 而不是语言错误. 不要把自己的设计缺陷推到C++上面, 然后反过来指责C++. 老实说, 这样的设计水平, 用任何语言都做不出来好的软件.

至于Linus说的C++是垃圾之类的话, 不用去当真. 他开发出了Linux, 是很好. 但不表示他说的话就是真理. 我相信那只是争论时候的激愤之言(而且有特定的环境, 某位老兄批评了一把他写的git软件, 有点小器). Linus是人, 不是神. 用不着顶礼膜拜.

软件质量取决于设计而不是开发语言.

posted on 2007-09-11 22:28 lovedday 阅读(1119) 评论(2)  编辑 收藏 引用 所属分类: ▲ C Program

评论

# re: C/C++之争 2007-09-12 22:41 LOGOS

比较认同你关于重用的理解  回复  更多评论   

# re: C/C++之争 2007-09-13 10:25 AMXTSHMF

主要大牛发话了,下面就成一锅粥了  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论