`

我对C++复杂性的一些认识

阅读更多

我学习使用C++,已经有差不多7,8年了。从当年在学校写小程序,到后来在公司写程序做设计。从VC++(虽然它不是标准C++),到后来嵌入式的C++,到现在在项目中,标准的C++。坦白说,C++确实很复杂,和Java, Objective-C,Python,Ruby这些语言比,它确实很复杂。这种复杂来自于几个方面:
[1] 编程的模式太多。面向过程,基于对象,面向对象,泛型。而且在面向对象的时候,它可以多继承(真正的多继承,不是那种多个接口一个父类的),虚继承,私有继承。
[2] 标准库的想法很完美,可是坦白说,库的级别太底层。举个例子std::string,没有提供一个函数可以将所有substr替换成另外一个,你需要自己用find和replace写一个;没有一些标准的库,譬如单元测试,Logger库。我知道有Boost,可是有的平台boost不能编译通过。
[3] 语言细节太诡秘,而且编译器之间有差别(实现)

我觉得[1]不是什么本质的问题,而是我们对待C++的问题。本来支持的东西多是好事,而且C++承诺你不用到一个属性的时候,这个属性存在不会拖你效率的后腿。一开始,我们根本不需要掌握多继承,虚拟继承,私有继承。因为这些在绝大多时候都用不上。只会共有继承,继承的时候用单个基类和多个接口(就是全部是纯虚函数)的那种,然后结合设计模式。基本可以解决设计上90%的问题。然后,你要知道C++有其他继承的这些功能,当你熟练了前面那些东西以后,并且发现在项目中确实上面的东西解决不了设计上的问题的时候,用上新的技术来解决问题。
[2] 这个东西就不好说了。虽然标准库设计的不错,但是对使用人员要求太高。现实中,合格的C++程序员真的不多,或者换个角度说,库做的还不够,有的时候它太灵活。我承认用C++的项目对性能都要求很高,但确实不需要那么高。所以,其实C++的标准库可以提供另一个好用但性能稍微有些缺陷的库,我们是可以接受的。就目前SL里面的string, io,这些库,真的需要改进。还有增加hashtable,增加logger,和UnitTest库。
[3] 这个问题和1一样,用到的时候再去了解,不用了解的太仔细。想当年,我把重载规则烂熟于心,现在还是忘的一干二净。因为太复杂太细节了。

现在我来看,虽然C++很复杂,但我至今认为它的功能是非常强大的。我是指在系统设计上,它支持的范式是如此之多。它的复杂性是因为我们太想掌握它的所有,其实,我们应该掌握那部分我们最应该掌握的:
面向过程,设计对象,面向对象,标准库。然后看看设计模式,多线程,操作系统的接口。然后就是多写程序,多看好的代码(我强烈建议不要看烂代码)。然后,就是开始用C++的思路去设计系统。在设计中去找到C++这些特性的应用场景,再去掌握它。那个时候,你就会自然而然的理解为什么有私有继承,需要多继承,需要虚继承,需要模板。你很多时候就会恍然大悟,哦,原来<The C++ Programming Language》上这段话是这个意思。慢慢的,你就能驾驭这种复杂性。
当然了,C++仍然缺乏一些其他语言的特性,我觉得:垃圾回收和反射。即使在电信金融这种项目中,垃圾回收都是有好处的。至少这个特性应该可选。反射,Java的反射可以为Java带来很多有用的设计方法,C++没有这个(0x也没有)。另外,我觉得C++的头文件机制也有必要修改(如果可以的话)。
当然,如果有个新项目来,我现在会首先考虑Java。因为C++对整个团队要求太高。而且开发效率太低了。在对性能要求很高的地方我用C++,其他不关键的地方我用Java,再变动大的地方我会选择用lua这种嵌入式语言。不使用模板,或者非常小范围的使用。不为别的,就好比设计模式没普及之前,面向对象经常被误用;模板设计模式没有普及或者总结之前,在大项目中少用模板,绝对有益处。

分享到:
评论
14 楼 smiletuna 2009-12-16  
内核 90%用C..或者说是C++里面better C的那部分。

13 楼 mxswl 2009-12-16  
Elrond 写道

程序员的主要精力还是要放在和需求作斗争上, 而不是去解开复杂的一团乱麻.


也正是这样,程序员民工化了。
我更愿意成为一个偏重于内核分析,底层探索的人,这才是程序员,这也是我逐渐远离java的原因。
当前,前提是你决定长期走技术路线。
12 楼 Elrond 2009-12-15  
C++强大在灵活上, 也复杂在灵活上, 很多时候也死在灵活上.

更多的时候, 我们靠编码规范一类的东西来自宫掉一些灵活性来换取稳定性和可读性.

程序员的主要精力还是要放在和需求作斗争上, 而不是去解开复杂的一团乱麻.

这差不多就是Java和C#流行的原因吧.
11 楼 ray_linn 2009-12-15  
wandou 写道
C++倒也不难,只是各种string的转换比较让人厌烦。


呵呵,那只是因为char压根没考虑Unicode的缘故,一般应该用TCHAR而不是Char.

CHAR为单字节字符。
WCHAR为Unicode字符,
如果当前编译方式为ANSI(默认)方式,TCHAR等价于CHAR,如果为Unicode方式,TCHAR等价于WCHAR。
在Windows下,应该采用Unicode字符而不是ANSI,因为所有的WindowsAPI都是unicode的(你说那些ANSI API,他们只是Unicode的Wrapper).

LPCSTR和LPSTR没区别,即以零结尾的字符串指针,相当于CHAR *。

一张对照表:

LPSTR = char *
LPCSTR = const char *
LPWSTR = wchar_t *
LPCWSTR = const wchar_t *
LPOLESTR = OLECHAR * = BSTR = LPWSTR(Win32)
LPCOLESTR = const OLECHAR * = LPCWSTR(Win32)

LPTSTR = _TCHAR *
LPCTSTR = const _TCHAR *

MC++可以用.net标准的String, 其他C++或者用QT的QString.
10 楼 wandou 2009-12-15  
C++倒也不难,只是各种string的转换比较让人厌烦。
9 楼 thinkx 2009-12-14  
楼主的说法我基本赞同。
其实C++的团队开发,应该按照水平分为两种人:一种人开发可重用的库,实际上在库的开发过程中,是难免会使用各种高级特性的,C++的各种特性都有非常合适的应用场景,没有多余的特性;大部分人则为普通编码,使用各种库而已。
项目中都是菜鸟不要玩太多C++。
8 楼 问风尘 2009-12-14  
C++比较红啊,有没有好的学习方法么?Visual C++2008入门经典 (http://item.taobao.com/auction/item_detail-0db2-04bef330c9d3300976e6e831afaa5f32.htm)
7 楼 sunzixun 2009-12-14  
c++ 在语法上比c复杂多了
6 楼 pister 2009-12-14  
truekbcl 写道

作为一个资深的c++程序员,你已经在c++江湖浪迹了很久。你知道,如果要写出一个工业级的c++库,你绕不开模板,oo乃至原生类型。由于这些东西有着天生的鸿沟,融合模板的静态FP特性,oo的动态特性,原生类型没有特性的特性,让你焦头烂额。各种traits,各种接口,更加上你不得不用的函数,而且这个函数还是c++的二等公民,你不得不小心的面对各种诡异的类型。你雄心勃勃的想打破动态与静态的鸿沟,想提供更加方便的借口,你又不得不拾起宏这个声名狼藉的东东来做粘合剂。好了,经过N久的努力,这一坨东西总算看起来融合在一起了,然后你开始编译。当你喝着茶开始make的时候,你基本上会祈祷万能的上帝给你开个金手指。上帝每时每刻都那么的忙,毕竟祈祷的人太多,所以绝大多数的时候,上帝是不会站在你这边。与其他程序一样,很正常的编译出错了。你其实也知道上帝不可能随时站在你这边,你也有心理准备。但是很不幸的是,编译器相当的愚蠢。它总是吐出一坨又一坨你完全上看不懂的东西。你唯一能懂的是,它们中间还有英文。你总是认为,从逻辑上看,代码这样编写是没有错的。你诅咒着标准委员会,为什么这个代码竟然不能通过。没办法,你不得根据英文google,最后只有查看标准。经过多方搜寻思考,你总算明白了为什么,而且又学会了一个细节。于是在你感到欣慰的同时,你不得不感叹这些牛人就是想得多。你也更敬畏c++了。日子不能总这样过,你想。经过这么多折磨,你准备放弃这样的屠龙技。虽然使用屠龙技搞出来的东东使用简单,修改灵活,效率高超,跨平台也好用,但是这妨碍了美好的人生。人生来就是享受的,你这样想。你可不想每天都生活在无尽的黑暗中,被玩着恶龙斗勇士的游戏。oo虽然有接口名限定,虽然代码臃肿,虽然接口巨大,虽然代码生成器很不灵活,但是简单,而且容易维护,毕竟条条道路通罗马,你决定就oo了。于是你流着口水仿佛又看到了你在春天里看着桃花盛开的第二春。yy是一件多么美好而让人喜闻乐见的事情啊......
呃,慢着,你还是醒醒吧,世界不是你想怎样就怎样的,你得适应社区不是?作为一个c++程序员,你接触的肯定是stl,boost这样顶级的库(什么?你没接触过?不要说你是c++程序员啊,这是给我们丢脸啊),里面可到处都闪烁着屠龙刀光,你这样一个巨鲸帮的三无产品也好意思拿出来献宝?c++社区用惯了简单方便接口的库使用者们,会用你这样的玩意?嗯?transform不能用了?咦?find不能用了?靠!连foreach也不能用了?婶可忍,叔不可忍!你说你不提交给社区,只给手下的小弟用?切,你不是以为小弟们来自火星吧?小弟们也是人哪,他们也是看着stl,boost的主啊。你当然可以用老大的权威让小弟们屈服,但是你头上的光环将会在小弟的眼中逐渐消失,直到只剩下鄙视。怎么样,你还认为你敢只用oo?
好了好了,你终于受不了了。冥思苦想,找到了一条出路:再见了吧c++,还是java吧,简单就是美啊。等着我,java,我来了!

上面写了一堆,算是我搞c++的一些感慨吧。不过我最喜欢的仍然是c++,就是因为极其强大的能力。而且大多数人还是想玩勇者斗恶龙的游戏,虽然多数是被恶龙斗。boost我看过不下7个库实现,基本上看得懂。自己写的东西,确实一直向着boost的方式靠近,其实也就是因为社区文化吧。从本身来说,我其实不喜欢java,java is not platform-independent, it is the platform。我喜欢cpp这样非平台的东东,自由。


油菜~
5 楼 truekbcl 2009-12-14  

作为一个资深的c++程序员,你已经在c++江湖浪迹了很久。你知道,如果要写出一个工业级的c++库,你绕不开模板,oo乃至原生类型。由于这些东西有着天生的鸿沟,融合模板的静态FP特性,oo的动态特性,原生类型没有特性的特性,让你焦头烂额。各种traits,各种接口,更加上你不得不用的函数,而且这个函数还是c++的二等公民,你不得不小心的面对各种诡异的类型。你雄心勃勃的想打破动态与静态的鸿沟,想提供更加方便的借口,你又不得不拾起宏这个声名狼藉的东东来做粘合剂。好了,经过N久的努力,这一坨东西总算看起来融合在一起了,然后你开始编译。当你喝着茶开始make的时候,你基本上会祈祷万能的上帝给你开个金手指。上帝每时每刻都那么的忙,毕竟祈祷的人太多,所以绝大多数的时候,上帝是不会站在你这边。与其他程序一样,很正常的编译出错了。你其实也知道上帝不可能随时站在你这边,你也有心理准备。但是很不幸的是,编译器相当的愚蠢。它总是吐出一坨又一坨你完全上看不懂的东西。你唯一能懂的是,它们中间还有英文。你总是认为,从逻辑上看,代码这样编写是没有错的。你诅咒着标准委员会,为什么这个代码竟然不能通过。没办法,你不得根据英文google,最后只有查看标准。经过多方搜寻思考,你总算明白了为什么,而且又学会了一个细节。于是在你感到欣慰的同时,你不得不感叹这些牛人就是想得多。你也更敬畏c++了。日子不能总这样过,你想。经过这么多折磨,你准备放弃这样的屠龙技。虽然使用屠龙技搞出来的东东使用简单,修改灵活,效率高超,跨平台也好用,但是这妨碍了美好的人生。人生来就是享受的,你这样想。你可不想每天都生活在无尽的黑暗中,被玩着恶龙斗勇士的游戏。oo虽然有接口名限定,虽然代码臃肿,虽然接口巨大,虽然代码生成器很不灵活,但是简单,而且容易维护,毕竟条条道路通罗马,你决定就oo了。于是你流着口水仿佛又看到了你在春天里看着桃花盛开的第二春。yy是一件多么美好而让人喜闻乐见的事情啊......
呃,慢着,你还是醒醒吧,世界不是你想怎样就怎样的,你得适应社区不是?作为一个c++程序员,你接触的肯定是stl,boost这样顶级的库(什么?你没接触过?不要说你是c++程序员啊,这是给我们丢脸啊),里面可到处都闪烁着屠龙刀光,你这样一个巨鲸帮的三无产品也好意思拿出来献宝?c++社区用惯了简单方便接口的库使用者们,会用你这样的玩意?嗯?transform不能用了?咦?find不能用了?靠!连foreach也不能用了?婶可忍,叔不可忍!你说你不提交给社区,只给手下的小弟用?切,你不是以为小弟们来自火星吧?小弟们也是人哪,他们也是看着stl,boost的主啊。你当然可以用老大的权威让小弟们屈服,但是你头上的光环将会在小弟的眼中逐渐消失,直到只剩下鄙视。怎么样,你还认为你敢只用oo?
好了好了,你终于受不了了。冥思苦想,找到了一条出路:再见了吧c++,还是java吧,简单就是美啊。等着我,java,我来了!

上面写了一堆,算是我搞c++的一些感慨吧。不过我最喜欢的仍然是c++,就是因为极其强大的能力。而且大多数人还是想玩勇者斗恶龙的游戏,虽然多数是被恶龙斗。boost我看过不下7个库实现,基本上看得懂。自己写的东西,确实一直向着boost的方式靠近,其实也就是因为社区文化吧。从本身来说,我其实不喜欢java,java is not platform-independent, it is the platform。我喜欢cpp这样非平台的东东,自由。
4 楼 ray_linn 2009-12-14  
mikeandmore 写道
ray_linn 写道
嘿嘿,你可以用MC++,有垃圾回收,有反射。。

那就不是RAII了


你要RAII也可以,想垃圾回收,你用gcnew关键字,想RAII,你用new关键字...各取所需。


最恨C++的就是友元,这种明显破坏封装性的东西。

一个例子就是QT里许多类把析构函数设为private,只能在其友元类中被delete.
3 楼 mikeandmore 2009-12-14  
ray_linn 写道
嘿嘿,你可以用MC++,有垃圾回收,有反射。。

那就不是RAII了
2 楼 七猫 2009-12-14  
深以楼主的说法为然。
我几年前写过一篇抱怨的短文,当时很多人不以为然。
http://blog.vckbase.com/bastet/archive/2006/01/21/17244.html
1 楼 ray_linn 2009-12-14  
嘿嘿,你可以用MC++,有垃圾回收,有反射。。

相关推荐

    谈我对java的一些认识

    Java是一种广泛使用的编程语言,以其...然而,这种强大功能的背后是复杂性的增加,这可能导致开发时间和资源的消耗。面对其他如.NET和Ruby等语言的竞争,Java需要不断优化和完善自身,以保持其在编程领域的领先地位。

    期末大型试验c++编写的银行模拟系统源代码

    描述中提到“不是很完美”,意味着开发者可能认识到项目存在一些局限性或者未完善的部分,但依然选择分享,以期对他人有所帮助。这显示了开发者愿意接受反馈并持续改进的态度,也是开源精神的一种体现。 【标签】:...

    Visual C++技术内幕(第四版).part6.rar

    因为经常有朋友或者读者与我讨论关于学习Visual C++或者MFC的话题,我想借此机会谈谈我对MFC的看法: 可以说,MFC是Windows桌面应用开发的C++ API,从早期MFC诞生到现在,Windows桌面风格经过了几次大的变动:从...

    Visual C++技术内幕(第四版)配套光盘

    因为经常有朋友或者读者与我讨论关于学习Visual C++或者MFC的话题,我想借此机会谈谈我对MFC的看法: 可以说,MFC是Windows桌面应用开发的C++ API,从早期MFC诞生到现在,Windows桌面风格经过了几次大的变动:从...

    Visual C++技术内幕(第四版).part4.rar

    因为经常有朋友或者读者与我讨论关于学习Visual C++或者MFC的话题,我想借此机会谈谈我对MFC的看法: 可以说,MFC是Windows桌面应用开发的C++ API,从早期MFC诞生到现在,Windows桌面风格经过了几次大的变动:从...

    C++编程开发学习的50条建议

    阅读这本书之后,你才能对自己是否真正掌握了C++有一个更清晰的认识。 #### 30. 学习编程的秘诀是:编程,编程,再编程。 - **解析**:理论知识很重要,但实践更加关键。通过不断地编写代码,才能真正提高编程能力...

    最小二行乘法 C++和Python实现源码带注释+数据分析报告

    通过此次试验,使我对最小二乘法有了更加深刻的认识,对其在生产实践和科学实验中的应用也有了一定的了解。在求解正则方程组时使用了SOR方法,也使得我更加熟练的掌握SOR求解方程组的方法。同时,通过将书中的理论...

    c++语言适合多大的孩子学?.docx

    如果一个人有机会学习两种不同年代的编程语言,就会深入地理解,这些人类历史上最聪明的人,他们的反思和对技术的认识。 因此,让孩子去参加信息学奥赛,我们并不聚焦于取得奖项荣誉,更希望孩子在学习过程中能够...

    Visual C++技术内幕(第四版).part1.rar

    因为经常有朋友或者读者与我讨论关于学习Visual C++或者MFC的话题,我想借此机会谈谈我对MFC的看法: 可以说,MFC是Windows桌面应用开发的C++ API,从早期MFC诞生到现在,Windows桌面风格经过了几次大的变动:从...

    Visual C++技术内幕(第四版).part2.rar

    因为经常有朋友或者读者与我讨论关于学习Visual C++或者MFC的话题,我想借此机会谈谈我对MFC的看法: 可以说,MFC是Windows桌面应用开发的C++ API,从早期MFC诞生到现在,Windows桌面风格经过了几次大的变动:从...

    Visual C++技术内幕(第四版).part3.rar

    因为经常有朋友或者读者与我讨论关于学习Visual C++或者MFC的话题,我想借此机会谈谈我对MFC的看法: 可以说,MFC是Windows桌面应用开发的C++ API,从早期MFC诞生到现在,Windows桌面风格经过了几次大的变动:从...

    Visual C++技术内幕(第四版).part5.rar

    因为经常有朋友或者读者与我讨论关于学习Visual C++或者MFC的话题,我想借此机会谈谈我对MFC的看法: 可以说,MFC是Windows桌面应用开发的C++ API,从早期MFC诞生到现在,Windows桌面风格经过了几次大的变动:从...

    C++MFC教程

    更重要的是理解并能运用C++的各种特性,这些在以后的开发中都会有很大的帮助,特别是利用MFC进行开发的朋友对C++一定要能熟练运用。 2、理解Windows的消息机制,窗口句柄和其他GUI句柄的含义和用途。了解和MFC各个...

    谈谈我对攻读计算机研究生的看法-作者不详

    文章列出了一些具体的技能要求,这些技能不仅是衡量是否有资格攻读研究生的标准,也是在研究生阶段取得成功的关键。具体包括但不限于: 1. **精通C++和汇编语言**。 2. **算法设计能力**:能够在短时间内设计出有效...

    有关学校教材订购系统的设计与实现

    这次课程设计让我认识到软件工程方法对项目开发的重要性和必要性,知道可以使得软件开发少走弯路,更容易开发出高质量的项目开发。按照软件工程的方法、软件的开发需要严格遵守其开发流程,作好软件设计的每一个流程...

    2022年关于java实习心得总结(五篇).docx

    通过实习,我对J2EE架构有了初步认识,了解到它如何提供多层结构和分布式计算的能力。 实习期间,我意识到不断学习新信息的重要性,尤其作为一名即将毕业的大学生,学习是保持工作活力的关键。实习不仅是技术提升的...

    C#微软培训资料

    14.4 继承中关于属性的一些问题.169 14.5 小 结 .172 第四部分 深入了解 C#.174 第十五章 接 口 .174 15.1 组件编程技术 .174 15.2 接 口 定 义 .177 15.3 接口的成员 .178 15.4 接口的实现 .182 ...

    大学生个人学习总结1000字.doc

    尽管还有待改进的地方,但我对自己取得的进步感到满意,也将继续努力,挑战自我,完善自我,使自己在大学的生活中更加全面发展。在这个过程中,我会不断反思,不断提升,以实现真正的个人成长。

Global site tag (gtag.js) - Google Analytics