C++11(及现代C++风格)

来源:互联网 发布:java 方法 编辑:程序博客网 时间:2024/04/28 19:37

过去的一年我在微软亚洲研究院做输入法,我们的产品叫“英库拼音输入法” (下载Beta版),如果你用过“英库词典” (现已更名为必应词典),应该知道“英库”这个名字(实际上我们的核心开发团队也有很大一部分来源于英库团队的老成员)。整个项目是微软亚洲研究院的自然 语言处理组、互联网搜索与挖掘组和我们创新工程中心,以及微软中国Office商务软件部(MODC)多组合作的结果。至于我们的输入法有哪些创新的 feature,以及这些feature背后的种种有趣故事… 本文暂不讨论。虽然整个过程中我也参与了很多feature的设想和设计,但90%的职责还是开发,所以作为client端的核心开发人员之一,我想跟大 家分享这一年来在项目中全面使用C++11以及现代C++风格(Elements of Modern C++ Style)来做开发的种种经验。

我们用的开发环境是VS2010 SP1,该版本已经支持了相当多的C++11的特性:lambda 表达式,右值引用,auto类型推导,static_assert,decltype,nullptr,exception_ptr等等。C++曾经饱受 “学院派”标签的困扰,不过这个标签着实被贴得挺冤,C++11的新feature没有一个是从学院派角度出发来设计的,以上提到的所有这些 feature都在我们的项目中得到了适得其所的运用,并且带来了很大的收益。尤其是lambda表达式。

免费会员网
说起来我跟C++也算是有相当大的缘分,03年还在读本科的时候,第一篇发表在程序员上面的文章就是Boost库的源码剖析,那个时候Boost库在国内还真是相当的阳春白雪,至今已经快十年了,Boost库如今已经是写C++代码不可或缺的库,被誉为“准标准库”,C++的TR1基本就脱胎于Boost的一系列子库,而TR2同样也大量从Boost库中取材。之后有好几年,我在CSDN上的博客几乎纯粹是C++的前沿技术文章,包括从06年就开始写的“C++0x漫谈”系列。(后来写技术文章写得少了,也就把博客从CSDN博客独立了出来,便是现在的mindhacks.cn)。 自从独立博客了之后我就没有再写过C++相关的文章(不过仍然一直对C++的发展保持了一定的关注),一方面我喜欢关注前沿的进展,写完了Boost源码 剖析系列和C++0x漫谈系列之后我觉得这一波的前沿进展从大方面来说也都写得差不多了,所以不想再费时间。另一方面的原因也是我虽然对C++关注较深, 但实践经验却始终绝大多数都是“替代经验”,即从别人那儿看来的,并非自己第一手的。而过去一年来深度参与的英库输入法项目弥补了这个缺憾,所以我就决定 重新开始写一点C++11的实践经验。算是对努力一年的项目发布第一版的一个小结。

09年入职微软亚洲研究院之后,前两年跟C++基本没沾边,第一个项目倒是用C++的,不过是工作在既有代码基上,时间也相对较短。第二个项目为Bing Image Search用javascript写前端,第三个项目则给Visual Studio 2012写Code Clone Detection,用C#和WPF。直到一年前英库输入法这个项目,是我在研究院的第四个项目了,也是最大的一个,一年来我很开心,因为又回到了C++。

这个项目我们从零开始,,而client端的核心开发人员也很紧凑,只有3个。这个项目有很多特殊之处,对高效的快速迭代开发提出了很大的挑战(研 究院所倡导的“以实践为驱动的研究(Deployment-Driven-Research)”要求我们迅速对用户的需求作出响应):

  1. 长期时间压力:从零开始到发布,只有一年时间,我们既要在主要feature上能和主流的输入法相较,还需要实现我们自己独特的创新feature,从而能够和其他输入法产品区分开来。
  2. 短期时间压力:输入法在中国是一个非常成熟的市场,谁也没法保证闷着头搞一年搞出来的东西就一炮而红,所以我们从第一天起就进入demo驱动的准 迭代式开发,整个过程中必须不断有阶段性输出,抬头看路好过闷头走路。但工程师最头疼的二难问题之一恐怕就是短期与长远的矛盾:要持续不断出短期的成果, 就必须经常在某些地方赶工,赶工的结果则可能导致在设计和代码质量上面的折衷,这些折衷也被称为Technical Debt(技术债)。没有任何项目没有技术债,只是多少,以及偿还的方式的区别。我们的目的不是消除技术债,而是通过不断持续改进代码质量,阻止技术债的滚雪球式积累。
  3. C++是一门不容易用好的语言:错误的使用方式会给代码基的质量带来很大的损伤。而C++的误用方式又特别多。
  4. 输入法是个很特殊的应用程序,在Windows下面,输入法是加载到目标进程空间当中的dll,所以,输入法对质量的要求极高,别的软件出了错误 崩溃了大不了重启一下,而输入法如果崩溃就会造成整个目标进程崩溃,如果用户的文档未保存就可能会丢失宝贵的用户数据,所以输入法最容不得崩溃。可是只要 是人写的代码怎么可能没有bug呢?所以关键在于如何减少bug及其产生的影响和如何能尽快响应并修复bug。所以我们的做法分为三步:1). 使用现代C++技术减少bug产生的机会。2). 即便bug产生了,也尽量减少对用户产生的影响。3). 完善的bug汇报系统使开发人员能够第一时间拥有足够的信息修复bug。

免费会员网
至于为什么要用C++而不是C呢?对于我们来说理由很现实:时间紧任务重,用C的话需要发明的轮子太多了,C++的抽象层次高,代码量少,bug相 对就会更少,现代C++的内存管理完全自动,以至于从头到尾我根本不记得曾遇到过什么内存管理相关的bug,现代C++的错误处理机制也非常适合快速开发 的同时不用担心bug乱飞,另外有了C++11的强大支持更是如虎添翼,当然,这一切都必须建立在核心团队必须善用C++的大前提上,而这对于我们这个紧 凑的小团队来说这不是问题,因为大家都有较好的C++背景,没有陡峭的学习曲线要爬。(至于C++在大规模团队中各人对C++的掌握良莠不齐的情况下所带 来的一些包袱本文也不作讨论,呵呵,语言之争别找我。)

0 0