C++的坑真的多吗?
先说明一下,我不希望本文变成语言争论贴。希望下面的文章能让我们客观理性地了解C++这个语言。(另,我觉得技术争论不要停留在非黑即白的二元价值观上,这样争论无非就是比谁的嗓门大,比哪一方的观点强,毫无价值。我们应该多看看技术是怎么演进的,怎么取舍的。)
目录
事由
周五的时候,我在我的微博上发了一个贴说了一下一个网友给我发来的C++程序的规范和内存管理写的不是很好(后来我删除了,因为当事人要求),我并非批判,只是想说明其实程序员是需要一些“疫苗”的,并以此想开一个“程序员疫苗的网站”,结果,@简悦云风同学直接回复到:“不要用 C++ 直接用 C , 就没那么多坑了。”就把这个事带入了语言之争。
我又发了一条微博:
@左耳朵耗子 : 说C++比C的坑更多的人我可以理解,但理性地思考一下。C语言的坑也不少啊,如果说C语言有90个坑,那么C++就是100个坑(另,我看很多人都把C语言上的坑也归到了C++上来),但是C++你得到的东西更多,封装,多态,继承扩展,泛型编程,智能指针,……,你得到了500%东西,但却只多了10%的坑,多值啊。
结果引来了更多的回复(只节选了一些言论):
- @淘宝褚霸也在微博里说:“自从5年前果断扔掉C++,改用了ansi c后,我的生活质量大大提升,没有各种坑坑我。”
- @Laruence在其微博里说: “我确实用不到, C语言灵活运用struct, 可以很好的满足这些需求.//@左耳朵耗子: 封装,继承,多态,模板,智能指针,这也用不到?这也学院派?//@Laruence: 问题是, 这些东西我都用不到… C语言是工程师搞的, C++是学院派搞的”
那么,C++的坑真的多么?我还请大家理性地思考一下。
C++真的比C差吗?
我们先来看一个图——《各种程序员的嘴脏的对比》,从这个图上看,C程序员比C++的程序员在注释中使用fuck的字眼多一倍。这说明了什么?我个人觉得这说明C程序员没有C++程序员淡定。
不要太纠结上图,只是轻松一下,我没那么无聊,让我们来看点真正的论据。
相信用过C++的程序员知道,C++的很多特性主要就是解决C语言中的各种不完美和缺陷:(注:C89、C99中许多的改进正是从C++中所引进的)
- 用namespace解决了很C函数重名的问题。
- 用const/inline/template代替了宏,解决了C语言中宏的各种坑。
- 用const的类型解决了很多C语言中变量值莫名改变的问题。
- 用引用代替指针,解决了C语言中指针的各种坑。这个在Java里得到彻底地体现。
- 用强类型检查和四种转型,解决了C语言中乱转型的各种坑。
- 用封装(构造,析构,拷贝构造,赋值重载)解决了C语言中各种复制一个结构体(struct)或是一个数据结构(link, hashtable, list, array等)中浅拷贝的内存问题的各种坑。
- 用封装让你可以在成员变量加入getter/setter,而不会像C一样只有文件级的封装。
- 用函数重载、函数默认参数,解决了C中扩展一个函数搞出来像func2()之类的ugly的东西。
- 用继承多态和RTTI解决了C中乱转struct指针和使用函数指针的诸多让代码ugly的问题。
- 用RAII,智能指针的方式,解决了C语言中因为出现需要释放资源的那些非常ugly的代码的问题。
- 用OO和GP解决各种C语言中用函数指针,对指针乱转型,及一大砣if-else搞出来的ugly的泛型。
- 用STL解决了C语言中算法和数据结构的N多种坑。
上述的这些东西填了不知有多少的C语言编程和维护的坑。少用指针,多用引用,试试autoptr,用用封装,继承,多态和函数重载…… 你面对的坑只会比C少,不会多。
C++的坑有多少?
C++的坑真的不多,如果你能花两到三周的时候读一下《Effecitve C++》里的那50多个条款,你就知道C++里的坑并不多,而且,有很多条款告诉我们C++是怎么解决C的坑的。然后,你可以读读《Exceptional C++》和《More Exceptional C++》,你可以了解一下C++各种问题的解决方法和一些常见的经典错误。
当然,C++在解决了很多C语的坑的同时,也因为OO和泛型又引入了一些坑。消一些,加一些,我个人感觉上总体上只比C多10%左右吧。但是你有了开发速度更快,代码更易读,更易维护的500%的利益。
另外,不可否认的是,C++中的代码出了错误,有时候很难搞,而且似乎用C++的人会觉得C++更容易出错?我觉得主要是下面几个原因:
- C和C++都没学好,大多数人用C++写C,所以,C的坑和C++的坑合并了。
- C++太灵活了,想怎么搞就怎么搞,所以,各种不经意地滥用和乱搞。
另外,C++的编译对标准C++的实现各异,支持地也千差万别,所以会有一些比较奇怪的问题,但是如果你一般用用C++的封装,继承,多态,以及namespace,const, refernece, inline, templete, overloap, autoptr,还有一些OO 模式,并不会出现奇怪的问题。
而对于STL中的各种坑,我觉得是程序员们还对GP(泛型编程)理解得还不够,STL是泛型编程的顶级实践!属于是大师级的作品,一般人很难理解。必需承认STL写出来的代码和编译错误的确相当复杂晦涩,太难懂了。这也是C++的一个诟病。
这和Linus说的一样 —— “C++是一门很恐怖的语言,而比它更恐怖的是很多不合格的程序员在使用着它”。注意我飘红了“很多不合格的程序员”!
我觉得C++并不适合初级程序员使用,C++只适合高级程序员使用(参看《21天学好C++》和《C++学习自信心曲线》),正如《Why C++》中说的,C++适合那些对开发维护效率和系统性能同时关注的高级程序员使用。
这就好像飞机一样,开飞机很难,开飞机要注意的东西太多太多,对驾驶员的要求很高,但你不能说飞机这个工具很烂,开飞机的坑太多。(注:我这里并不是说C++是飞机,C是汽车,C++和C的差距,比飞机到汽车的差距少太多太多,这里主要是类比,我们对待C++语言的心态!)
C++的初衷
理解C++设计的最佳读本是《C++演化和设计》,在这本书中Stroustrup说了些事:
1)Stroustrup对C是非常欣赏,实际上早期C++许多的工作是对于C的强化和净化,并把完全兼容C作为强制性要求。C89、C99中许多的改进正是从C++中所引进。可见,Stroustrup对C语言的贡献非常之大。今天不管你对C++怎么看,C++的确扩展和进化了C,对C造成了深远的影响。
2)Stroustrup对于C的抱怨主要来源于两个方面——在C++兼容C的过程中遇到了不少设计实现上的麻烦;以及守旧的K&R C程序员对Stroustrup的批评。很多人说C++的恶梦就是要去兼容于C,这并不无道理(Java就干的比C++彻底得多),但这并不是Stroustrup考虑的,Stroustrup一边在使尽浑身解数来兼容C,另一方面在拼命地优化C。
3)Stroustrup在书中直接说,C++最大的竞争对手正是C,他的目的就是——C能做到的,C++也必须做到,而且要做的更好。大家觉得是不是做到了?有多少做到了,有多少还没有做到?
4)对于同时关注的运行效率和开发效率的程序员,Stroustrup多次强调C++的目标是——“在保证效率与C语言相当的情况下,加强程序的组织性;能保证同样功能的程序,C++更短小”,这正是浅封装的核心思想。而不是过渡设计的OO。(参看:面向对象是个骗局)
5)这本书中举了很多例子来回应那些批评C++有运行性能问题的人。C++在其第二个版本中,引入了虚函数机制,这是C++效率最大的瓶颈了,但我个人认为虚函数就是多了一次加法运算,但让我们的代码能有更好的组织,极大增加了程序的阅读和降底了维护成本。(注:Lippman的《深入探索C++对象模型》也说明了C++不比C的程序在运行性能低。Bruce的《Think in C++》也说C++和C的性能相差只有5%)
6)这本书中还讲了一些C++的痛苦的取舍,印象最深的就是多重继承,提出,拿掉,再被提出,反复很多次,大家在得与失中不断地辩论和取舍。这个过程让我最大的收获是——a) 对于任何一种设计都有好有坏,都只能偏重一方,b) 完全否定式的批评是不好的心态,好的心态应该是建设性地批评。
我对C++的感情
我先说说我学C++的经历。
我毕业时,是直接从C跳过C++学Java的,但是学Java的时候,不知道为什么Java要设计成这样,只好回头看C++,结果学C++的时候又有很多不懂,又只得回头看C,最后发现,C -> C++ -> Java的过程,就是C++填C的坑,Java填C++的坑的过程。
注,下面这些东西可以看到Java在填C/C++坑:
- Java彻底废弃了指针(指针这个东西,绝对让这个社会有几百亿的损失),使用引用。
- Java用GC解决了C++的各种内存问题的诟病,当然也带来了GC的问题,不过功大于过。
- Java对异常的支持比C++更严格,让编程更方便了。
- Java没有像C++那样的template/macro/函数对象/操作符重载,泛型太晦涩,用OO更容易一些。
- Java改进了C++的构造、析构、拷贝构造、赋值。
- Java对完全抛弃了C/C++这种面向过程的编程方式,并废弃了多重继承,更OO(如:用接口来代替多重继承)
- Java比较彻底地解决了C/C++自称多年的跨平台技术。
- Java的反射机制把这个语言提升了一个高度,在这个上面可以构建各种高级用法。
- C/C++没有一些比较好的类库,比如UI,线程 ,I/O,字符串处理等。(C++0x补充了一些)
- 等等……
当然时代还在前进,这个演变的过程还在C#和Go上体现着。不过我学习了C -> C++ -> Java这个填坑演进的过程,让我明白了很多东西:
- 我明白了OO是怎么一回事,重要的是明白了OO的封装,继承,和多态是怎么实现的。(参看我以前写过的《C++虚函数表解析》和《C++对象内存布局》)
- 我明白了STL的泛型编程和Java的各种花哨的技术是怎么一回事,以及那些很花哨的编程方法和技术。
- 我明白了C,C++,Java的各中坑,这就好像玩火一样,我知道怎么玩火不会烧身了。
我从这个学习过程中得到的最大的收获不是语言本身,而是各式各样的编程技术和方法,和技术的演进的过程,这比语言本身更重要!(在这个角度上学习,你看到的不是一个又一个的坑,你看到的是——各式各样让你可以爬得更高的梯子)
我对C++的感情有三个过程:先是喜欢地要死,然后是恨地要死,现在的又爱又恨,爱的是这个语言,恨的是很多不合格的人在滥用和凌辱它。
C++的未来
C++语言发展大概可以分为三个阶段(摘自Wikipedia):
- 第一阶段从80年代到1995年。这一阶段C++语言基本上是传统类型上的面向对象语言,并且凭借著接近C语言的效率,在工业界使用的开发语言中占据了相当大份额;
- 第二阶段从1995年到2000年,这一阶段由于标准模板库(STL)和后来的Boost等程式库的出现,泛型程式设计在C++中占据了越来越多的比重性。当然,同时由于Java、C#等语言的出现和硬件价格的大规模下降,C++受到了一定的冲击;
- 第三阶段从2000年至今,由于以Loki、MPL等程式库为代表的产生式编程和模板元编程的出现,C++出现了发展历史上又一个新的高峰,这些新技术的出现以及和原有技术的融合,使C++已经成为当今主流程式设计语言中最复杂的一员。
在《Why C++? 王者归来》中说了 ,性能主要就是要省电,省电就是省钱,在数据中心还不明显,在手机上就更明显了,这就是为什么Android 支持C++的原因。所以,在NB的电池或是能源出现之前,如果你需要注重程序的运行性能和开发效率,并更关注程序的运性能,那么,应该首选 C++。这就是iOS开发也支持C++的原因。
今天的C++11中不但有更多更不错的东西,而且,还填了更多原来C++的坑。(参看:C++11 Wiki,C++ 11的主要特性)
总结
- C++并不完美,但学C++必然让你受益无穷。
- 是那些不合格的、想对编程速成的程序员让C++变得坑多。
最后,非常感谢能和“@简悦云风”,“@淘宝诸霸”,“@Laruence”一起讨论这个问题!无论你们的观点怎么样,我都和你们“在一起”,嘿嘿嘿……
(全文完)
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《C++的坑真的多吗?》的相关评论
我代表“很多不合格的程序员”表示,“我对C++的感情只有二个过程:先是喜欢地要死,然后是恨地要死”
最早学的语言就是C++,觉得学会了就无所不能。结果学用起来总是把自己折磨的要死,复杂得要死才是真相。
自从C++转向纯C,再也没痛苦过了。而且现在偶尔吐糟一下C++的各种坑,还觉得精神倍爽!
客观地讲,就是C++为了填坑带来的复杂性超过了我这种的“不合格的程序员”容忍程度。
所以我宁愿接受C少许的美中不足,也不愿意补一个坑就引入数个更大的坑外加学习复杂度
引用一句我比较赞同的编程语言的设计哲学,scheme语言的:Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.
c++的坑只有一个:太复杂了。
严重同意!@zino
C++真心不好用。但是一个字符串就有string,wstring还有原始的char[]等各种表现形式。更别说第三方库还会用神马QString,CString,真心晕得要死。字符串编码的问题就更不说了。
洋洋洒洒一sb
人生苦短,我用python! 哈哈@edwinaclau
你不能试图说哪个更好,你说了,你就会发现自己掉坑里了。
严重同意楼主的看法,各种语言都有坑,还是看自己如何避免吧
不能一味吐槽
c++应该弃掉兼容c的部分,变为真正完全面向对象的语言 正是因为兼容c,再加上自身的改进,导致了c++庞大而复杂
突然想知道好奇号是用哪种语言搞的 ^ ^
这篇文章和前面的文章对比的一看,有很明显的主观性,看来博主是一位对c++有着深厚情感的fans。
真正理解一门语言,用好一门语言才是王道
额…本人正在入门,还是先把C学好再说,我可不希望我是不合格的程序员祸害人间
非常赞同,知其然也要知其所以然。
路过
正常使用python,逼不得已用C
另:
@DotNetGeek
请不要破坏 酷壳 这么好讨论的氛围,留言讨论请自觉。
C++ 程序员都不觉得 C++ 那么多坑. 觉得 C++ 坑多的只能说是 C 程序员++.
习惯性地认为 C++ 是 A better C 或者 C with classes 才会抱着 C 来跟 C++ 比较, 其实这完全是两种语言.
C++ 兼容 C 当年是出于营销考虑的吧 (玩笑), 同意 @purevirtual 的说法, 如果再弄个语言保留 C++ 的长处删去对 C 的一些兼容就很好了. 尤其是指针. 特别是指针 cast.
“是那些不合格的、想对编程速成的程序员让C++变得坑多”;但是说来我学编程也这么久了,现在都不敢说自己会C++,偶尔想实现什么高级功能还要到网上查一查。这门语言庞杂的特性让人实在做不到触类旁通,融汇贯通,除非坚定地使用它的一个子集,否则一不小心就错了。这还得算是C++的一大坑。
“不是有坑,是因为你不会”,这理由真是不怎么样。
这结论等同于在说“你哪种语言写的熟就用哪种吧。”
我也曾经学过一段时间的C++,但是放弃了,太复杂。
在C和C++ 两个门派中,我坚定的用户C。
我们最近在培训写出更好更安全,bug更少的C代码。
讲了一堆技巧,其实根本技巧就是 你要对的起C语言对你的信任。
C++太复杂了。
历史定位?请问这个历史定位是你定的吗?C++不能接C的班的地方多了去了,C++使用模板等特性以后很难确保获得安全的能在内核态运行的代码…
@阿汉
孩子,学Java吧,博主他们公司招人过去都是用Java…
我个人认为c++的学习要从标准c++开始学起,不要一开始就接触qt之类。
bs的那本书非常值得一看。
Python的确不仰仗于委员会,而是仰仗于一个贤明的独裁者,好在这个独裁者还没打算退休,不过光是2.x和3.0之争就够书一笔了吧,又何必嘲讽C++的委员会设计呢。
关于《Imperfect C++》这本书,我相信你是读过的,你真的认为这是“专门抱怨C++不足”的一本书吗?
C++最大的问题是把复杂性统统对使用者暴露了出来,以泛型为例,使用Java和C#编程的人当中对这两门语言的泛型机制真正了解的可能不多,他们知道的仅仅是一个神奇的
如果你能提议一种匹配得上C++的高性能反射方案,我相信标准委员会虽然官僚但仍然乐于接受。
哦,这是我见过的最肤浅的语言比较:“我经常使用的A语言能做xxx,而B语言竟然不提供这支持——B语言竟然不能让我使用A语言的思考方式来使用它,B语言真实渣”。
很遗憾,你似乎并没有理解generic typing,对于习惯了动态语言思维的人而言,将其看作一种静态的duck typing其实是很方便的,而SFINAE只是一个静态的“method missing”罢了。
绝大多数是由不合格的——特别是C程序员出身的——C++写手造成的。
你能告诉我这简短的代码背后,Python为你做了哪些事情吗?
很高兴C++不是由你来设计,否则它的坑一定比现在多十倍…
你是说比用强制缩进来体现代码逻辑还奇特?语言评论帖里总会出现各种沙文主义的言论,真是有意思的现象。
Concept被否决是因为现在的设计还不够成熟,出错信息的设计不包含在C++的设计当中,实际上很少有哪个语言的出错信息对新手用户是友好的。
我真是佩服你的自大,Andrei本人作为有影响力的一员,你认为…我想我还是省略下面的话比较好…
你其实完全不熟悉STL,何必硬要凑上呢?你的评论洋洋洒洒,但总结起来只有一句话:我不熟悉or我不喜欢==不好。
依据作者提出的观点可以总结出:关键在于学cpp可以让你收获很多。我想知道,这是收获在学其他的语言时候不能获得吗?能不能更快,更好的获得呢?
C++在国内外备受非议已经有很多年历史,国内以游戏界编程偶像云风的某篇博文为首,掀起了轰轰烈烈的反C++复C运动,国外则以Linus的一篇牛粪开头的帖子为起点重燃战火。在C++社区的周围,使用各种语言的社区正在结成一个包围网,来围剿这门备受“争议”的语言。
其实在围剿C++的包围网(不知道我为啥总想起信长包围网)当中,各路动态语言的新贵,基本是来秀自己的便利语法的优越感的,对于这类攻击的回应倒还很简单,C++是以性能和大项目组织见长,和这些货色走的不是一套路线。
接下来的攻击主要来自Java社区(也会有.NET社区的一些活力掺杂其间),Java社区所秉持的优势主要有三大宝具: 简单傻瓜易用(包括IDE),跨平台,库和框架丰富而庞大。但是Java社区一直无法直面的一个问题是:性能,无论多么优秀的JIT把多么复杂的数学运算优化得和本地代码一样快,作为产品的Java代码始终无法摆脱迟缓和臃肿。这是语言的功劳,也是语言的过失——我相信萨丕尔·伍尔夫假说在程序设计界是成立的——Java引以为傲的让程序员更专注于逻辑带来的是程序员对性能的忽视,好吧,现在硬件便宜,这正是IBM之流的硬件商最喜欢听到的…
对于这些基于虚拟机/运行时的语言,性能始终是其无法承受之痛,于是C扩展这一救命稻草粉墨登场了。C扩展救得了他们吗?有时能,当然付出的代价,是打破其吹嘘的安全性,以及丧失了它们轻快的语法而拖泥带水的C代码..美好的虚拟机上的世界和虚拟机下的泥泞的现实就这么凑合在了一起,只有.NET和Lua在一旁笑而不语。
在包围网当中,对C++攻击最狠,最具代表性的还是C社区。C社区的意见大致可以总结为三点:
1. C++的性能我能达到
2. C++太复杂,不如C简单
3. 动态语言性能的不足,都可以依靠C来填补
针对这三点,C++社区自然也有应对:
1. 不仅性能,C能做的,C++都能做
2. 如果愿意,C++能做到和C一样简单,而C++具有的表达能力,C永远也无法企及
3. 参见1,同时C++甚至能做到更好,比如Luabind
基本上,双方在这些观点上是想吃不下的,最后只能归结为哲学,信仰,审美,等等形而上的层面。
可以说,对C++的围攻中,最有杀伤力的就是来自C的攻击,因为这是一场旷日持久的圣战,嗯,使用这个词不是故意煽情,而是这的确是观念之争。
下面的故事来自我自己的亲身经历,我们从中能看出C和C++程序员的矛盾是如何的不可调和,而所谓的C程序员对C++和C++程序员又是如何的包含恶意:
有这样一个项目J,大概有十几年历史了,项目中混合使用了C和C++。但是关于项目的代码风格和约定,基本上是一份C的代码风格和约定,关于C++的内容几乎没有。当你打开其中的C++代码,你就会发现,其中的代码大部分是形如:
class foo {
int a, b, c;
bool init();
bool close();
bool do();
};
这样的风格,事实上,存在着一份不成文的C++风格约定:
不要使用模板,和任何与模板有关系的东西,比如STL,Boost,禁止使用标准库,不仅是STL,即使是ANSI-C的标准库也尽量不要使用,禁止任何运算符重载,异常,禁止使用引用作为函数参数类型——必须使用指针,禁止使用static关键字,除非是用来声明文本域可见的函数,禁止使用命名空间,用char *表示字符串,禁止使用new和delete(这一禁令的理由最为黑色幽默,因为new和delete和导致在Linux上对libstdc++.so的依赖,而部分Linux发行版上默认不会安装这个库…)可能还有很多禁止,但我记不太清了,实在是太多了,但很奇怪,就是没有禁止使用C++而采用纯C。
作为一个C++程序员,当第一次遭遇代码评审的时候,噩梦袭来,依照上述不成文的惯例,一份还算是符合现代C++精神的代码被改成了儿童不宜的一坨,在据理力争之下,唯一的引用参数终于在拷贝构造函数里保存了下来,new和delete也被替换成了经过包装的malloc和free——按照惯例,他们为每一个类编写一个staitc newInstance函数来代替new,相应的,在编写一个不static的kill函数来代替delete——实际上是在对象析构前就对调用 free( this )!!!!!!!——更绝的是,当他们看到在构造函数中分配资源而在析构函数中释放资源的代码的时候,那种看见了Nyarulatohotip一样的表情,真应该让Lovecraft来看看…为了向他们解释这种他们头一次听说的名叫RAII的idiom,最后不得不搬出了Java 7中引入的try-with-resource statement作为参照,他们总算明白了这是一种自动管理资源的技巧,当然对于什么叫异常安全就别指望能在一天下午同时科普了….
看到这里,诸位看官或许认为我编造了一个天方夜谭,然而事实上,这是我前几周的亲身经历,那些无比仇恨C++的伟大的C程序员来自一个著名企业的Java虚拟机核心团队,他们当中有人是工作十多年的“富有经验的开发者”(至少经理们是这样认为)。这次伤透了心的代码审查给那个倒霉的C++程序员带来的是大量的修改工作(同时还得对各种异味忍者恶心)——以及代码提交的延迟。对此大为光火的TechLead(他当然无条件的支持来自总部的“资深专家们”的意见)说出了一句发人深思而又富含哲理的偈语:
“C++代码的可读性是很糟糕的,因为你把C++代码拿给(几乎只懂C的)C程序员读的时候,他们都看不懂或者会搞错”。(可是为什麽不干脆禁用C++呢,像Linus做的那样?)
在下认为这个故事生动的反映了C++在业界的应用状况,All valid C program is valid C++ program(K&R, Practice of Programming),但是,Not all valid C programmer is valid C++ programmer. C is the sin of C++。对于C++最恐怖和致命的伤害,不是来自于他和其它语言比较的差异,而是来自于他无法将那些Substandard的C程序员排除在外,而C可以反过来这么做,只需要在代码里定义几个用C++关键字命名的核心结构就行了,比如class,template等等。这是一个劣币驱逐良币的过程,C++仅仅作为a better C是没有前途的,第二系统综合症足以要了它的命。
要克服C这一原罪,C++需要更进一步的进化,希望我能活着看到那一天…
相对c来说,c++开发超过5万行以上的代码还是比较有优势的,
如果熟悉使用boost智能指针,stl容器来管理内存,内存管理也不是什么大问题。
用C的一大问题是,如果不使用面向对象的开发方法,代码规模大的以后很难控制,如果使用面向对象的开发,C语言提供的东西对开发者来说,太少了。
语言诞生的时代与当时软件开发理论有很深的联系。 c诞生的年代,使用面向对象去开发软件不是主流,所以用C语言,却用面向对象去开发,完全是硬把2种不相关的东西用在一起。
看到云风用abi兼容性来攻击C++,我就笑了,abi东西在一个开源项目中是问题吗?在商业项目中,内部模块之间用的着考虑abi兼容性?要考虑abi兼容性这东西的场合,一般就是开发平台级库和商用动态库需要考虑,实际需要考虑的场合不多。
就算要考虑abi兼容性,难道不能用纯C作接口,用c++作实现?当然是指规模大的项目,这方面有一个开源项目sipxecs,百万级别的开源项目,做的很好,C做接口,c++写实现。
一些人为了攻击C++,无所不其用,不管用的上的用不上的都拿来当虎皮扯。
我赞同博主所说的填坑顺序,我是顺着学下来的,感觉c++除了要记得东西多一些,别的还行,java也学得很顺,我遇到过上来就学java的,而且也没什么计算机基础,和我抱怨java太难了,我说c++能搞死你。果然后来学c++痛苦的要死。学c的时候又小痛苦了一下
语言,只有搞懂了理论的因果,采能真正的掌握。
论运行效率,编译效率,c++不及c,论开发效率,又不及ruby这类高级语言。
c++流行只是因为c的流行,c的流行是因为操作系统都用c写,api接口能完美兼容。
用了七八年的c++了,并且现在还在用,然而对它的感觉是从:惊喜->喜爱->厌恶,这么一个过程。
如果要做底层开发,就用c,如果要做高层开发,就用java,ruby,python这种语言。
@icosagon
我现在做的一个项目就是用c++开发堆积起来的,快500万行了。到了这个级别的app,我认为oo只会让整个系统越搞越混乱。
B.T.W
用服务器级别的机器去编译整个项目,也得一个多小时。以效率高而著称的c++,在此刻是如此的让人觉得讽刺。
@Rasefon
oo会让整个系统越搞越乱?现在大规模软件设计方法被你一个项目否定了?
500万行的项目,难道你准备用面向过程的方法进行设计?
500万行的项目,没有一个好的设计,或者不做重构,无论用什么语言,都只会越搞越乱。
上面有人说了,Linux的设计很好,我倒想知道好在哪里?
感觉上千万行的代码设计好都是扯谈的。
@YY
对不起不学JAVA很久了
@icosagon
不是一个项目的问题。
比如一个大规模软件,如果你是初始设计者,自然你对你自己的负责的那块东西的整体架构会很熟悉,你会用你喜欢的模式去设计,会用到很多oo的特性。然后你离职了,来了几个新人,他们对你的设计一无所知,需要花费更多的时间去了解这些架购的结构,而不是应用本身的业务逻辑。比起c这种纯粹的过程式语言,我没发觉c++有什么优势。人员的流动对于整个软件行业来说很普遍。
而且对于c++来说,几乎没人愿意用它去写底层,比如驱动程序,我举个例子,windows的打印机的驱动,最早就是一些DDI的接口,后来微软把它封装了一层,用c++做了个壳子,做成了com。结果呢,对于各个厂商而言,底层的库还是用c写的,只是会额外多做很多无用功,并且引入新的bug。
而对于例如web应用这种上层的开发来说,c++也没有优势可言,到现在为止还没看到过一个full stack的web框架是用c++设计并实现的。
还是那句话,c++只会让你徒增烦恼而已。
@lltg
这其实也是否定了c++:哪门语言容易熟,才容易不犯错。。。。c++显然不是
我怎么觉得C++要比Java容易,除了没人用的多继承有点复杂,其他的用法都很简单明了,java还要学线程,网络编程。 那些essential, exceptional, C++编程规范等书籍里面都是几条重复的规则在讲来讲去,很多规则明显就不会用错,居然也可以讲几页。
无论使用什么,用到深处都是一种状态:形和神的统一
@Rasefon
难道用C,用面向过程的方法进行设计,后来的人就能很容易接手?
至少oo让后来的人还有脉络可寻,从整体入手,了解模块层次划分,调整局部,最后达到可维护的目标。
500万行项目,使用面向过程的方法?你会让后来的人痛不欲生,因为看上去处处可入手, 一 一对应的功能都有函数可看,但实际上你敢改吗? 你改了根本不知道会影响到其它什么模块。
这就好像飞机一样,开飞机很难,开飞机要注意的东西太多太多,对驾驶员的要求很高,但你不能说飞机这个工具很烂,开飞机的坑太多。(注:我这里并不是说C++是飞机,C是汽车,C++和C的差距,比飞机到汽车的差距少太多太多,这里主要是类比,我们对待C++语言的心态!)
===
1) 如果你们公司烂人多,就不要让他们开飞机.
2) 你们公司是不是现在将来都只请50万年薪的人.
3) 如果不是。。。。
@Rasefon
用驱动和web来否定c++? 那能否用桌面软件来否定c?
喜欢C的偏执狂们(比如我),又像用一些比较时髦的语言特性的,看看Vala吧。。。
至于到底谁好谁外,没啥好争的,至少GNU的项目基本都是C,最多加上C++的bingding。。。。
@icosagon
对啊,你看我说的就是不同的应用场景c++和其他语言比没优势。
桌面软件的话,发展到今天,肯定也是像c#这类语言更好用。
Why Vala?
Many developers want to write GNOME applications and libraries in high-level programming languages but can’t or don’t want to use C# or Java for various reasons, so they are stuck with C without syntax support for the GObject type system. The Vala compiler allows developers to write complex object-oriented code rapidly while maintaining a standard C API and ABI and keeping the memory requirements low.
C# and Java libraries can’t be used the same way as native GObject libraries from C and other languages and can’t be accepted as part of the GNOME Platform. Managed applications also suffer from usually higher memory requirements which is not acceptable in some situations.
valac produces C source and header files from Vala source files as if you’ve written your library or application directly in C. Using a Vala library from a C application won’t look different than using any other GObject-based library. There won’t be a vala runtime library and applications can distribute the generated C code with their tarballs, so there are no additional run- or build-time dependencies for users.
GOOD