学习C++:实践者的方法(上)

发表于:2012-1-05 09:31

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

  建议2:养成随时查阅资料和文档的习惯。

  “查文档”几乎可以说是作为一个程序员最重要的能力(是的,能力)了;它是如此重要,以至于在英文里面有一个专门的缩写——RTFM。为什么这个能力如此重要,原因很简单:编程领域的知识太鸡零狗碎了。不仅知识量巨大,而且知识的细节性简直是任何学科都无与伦比的(随便找一个框架类库看看它的API文档吧)。所以,把如此巨量的信息预先放在脑子里不仅不实际,而且简直是自作孽。你需要的是“元能力”,也就是查文档的能力——从你手头遇到的问题开始,进行正确合理的分析,预测问题的解决方案可能在什么地方,找到关于后者的资料,阅读理解,运用。

  同样,在C++中也是如此,如果你从学习C++一开始就抱着这种态度的话,那么即便等到面试的时候被问到某个语言细节,你也可以胸有成竹的说你虽然并不知道这个细节,但在实际编码中遇到相应问题的时候肯定会找到合适的参考资料并很快解决问题(解决问题,才是最终目的)。当然,更大的可能性是,你在平常编码中已经接触过了最常见的那80%的陷阱和技巧了,由于你用的是实践指导性的学习方式,所以你遇到的需要去学习的陷阱和技巧几乎肯定都是常见场景下的,比没头苍蝇似的逮住一本C++“经典”就“细细研读”的办法要高效N倍,因为在没有实践经验的情况下,你很可能会认为其中的每个技巧,每个陷阱,都是同样概率发作的。

  为什么市面上的C++书热衷于那些细节和技巧呢?

  你用一个天生用来开啤酒瓶的工具开了啤酒瓶,不但啥成就感也没有,而且谁也不会觉得你牛13。然而,如果你发明了一种用两根筷子也能打开啤酒瓶的办法,或者你干脆生就一口好牙可以把瓶盖啃开,那也许就大不一样了。人家就会觉得你很好很强大。

  事实8:每个人都喜欢戴着脚镣跳舞。

  也就是说,如果你用一个天生为某个目的的工具来做他该做的事情,没有人会喝彩,你也不会觉得了不起。但如果你用两个本身不是为某个目的的工具组合出新功能的话,你就是“创新”者(尽管也许本来就有某个现成的工具可用)。

  而C++则是这些“创新”的土壤,是的,我说的就是无穷无尽的workarounds和惯用法。但问题是,这些“创新”其实根本不是创新,你必须认识到的是,他们都只不过是在没有first-class解决方案的前提下不得已折腾出来的替补方案。是的,它们某种程度上的确可以叫创新,甚至研究可行的解决方案本身也是一件非常有意思的事情,但——

  事实9:我知道它们很有趣,但实际上它们只是补丁方案。

  是的,不要因为这些“创新”方案有趣就忍不住一头钻进去。你之所以觉得有趣是因为当你一定程度上熟悉了C++之后,C++的所有一切,包括缺陷,对你来说就成了一个“既定事实”,一个背景,一个习以为常的东西(人是有很强的适应性的)。因此,当你发现在这个习以为常的环境下居然出现了新的可能性时,你当然是会欢呼雀跃的(比如我当年读《ModernC++Design》的时候就有一次从早读到晚,午饭都没吃),然而实际上呢?其它语言中也许早就有first-class的支持了,其它语言也许根本不需要这个惯用法,因为它们就没有这些缺陷。此外,从实践的角度来说,更重要的是,这些“解决方案”也许你平时编程根本就用不到。

  不,我当然不是说这些补丁方案不重要。正如前面所说,C++中繁杂的技巧并非空穴来风,总有实际问题在背后驱动的。但问题是,对于我们日常编程来说,这些“实际问题”简直是八杆子打不着的。犯不着先费上80%的劲儿把20%时候才用到的东西揣在脑子里,用的时候查文档或书就行了。

  看到这里,塑造C++中特定的心态哲学的另一个原因想必你也已经知道了。实际上,这个原因才是真正根本的。前面说的一个原因是C++书籍市场(教育)造就的,然而为什么人们喜欢写这些书呢?进一步说,为什么人们喜欢读这些书呢?(我承认,我也曾经读得津津有味。)答案很简单:心理。每个人都喜欢戴着脚镣跳舞(事实8)。认识到这一点不是为了提倡它,而是只有当我们认识到自己为什么会津津有味地去钻研一堆补丁解决方案的时候,我们才真正能够摆脱它们的吸引。

  总而言之,C++的复杂性只是一个必要条件,并非问题的根本症结。根本症结在于人的心理,每个人都喜欢戴着脚镣跳舞,并且以为是“创新”。意识到这一点之后可以帮我们避免被各种各样名目繁多的语言细节和技巧占去不必要的时间。

  然而,C++的复杂性始终是一个不可回避的现实。C++中有大量的陷阱和缺陷,后者导致了数目惊人的惯用法和workarounds。不加选择的全盘预先学习,是非常糟糕的做法,不仅低效,而且根本没有必要,实在是浪费生命。爱因斯坦曾经说过,“我只想知道‘他’(宇宙)的设计理念,其它的都是细节”。然而,正如另一些读者指出的,如果对C++中的这些细节事先一点都没有概念的话,那么实际编码中一旦遇到恐怕就变成没头苍蝇了,也许到哪里去RTFM都不知道。这也是为什么那么多C++面试都会不厌其烦地问一些有代表性的语言细节的原因。

  把细节全盘装在脑子里固然不好,但对细节一无所知同样也不是个办法。那么对于C++程序员来说,在学习中究竟应该以怎样的态度和学习方法来对付C++的复杂性呢?其实答案也非常简单,首先有一些很重要&必须的语言细节&特性是需要掌握的,然后我们只需知道在C++中大抵有哪些地方有复杂性(陷阱、缺陷),那么遇到问题的时候自然能够知道到哪儿去寻找答案了。具体的建议在后文。

  C++的复杂性分类

  本来这一节是打算做成一个C++复杂性索引的,然而一来C++的复杂性太多,二来网上其实已经有许多资料(比如BjarneStroustrup本人的C++ TechnicalFAQ就是一个很好的文档),加上市面上的大多数C++书里面也不停的讲语言细节;因此实际上我们不是缺乏资料,而是缺乏一种索引这些资料的办法,以及一种掌控这些复杂性的模块化思维方法。

  由于以上原因,这里并不详细罗列C++的复杂性,而是提供一个分类标准。

  C++的复杂性有两种分类办法,一是分为非本质复杂性和本质复杂性;其中非本质复杂性分为缺陷和陷阱两类。另一种分类办法是按照场景分类:库开发场景下的复杂性和日常编码的复杂性。从从事日常编码的实践者的角度来说,采用后一种分类可以让我们迅速掌握80%场景下的复杂性。

54/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号