Boost程序库完全开发指南:深入C++”准”标准库(第5版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

推荐序

最近一年,我电话面试了数十位C++应聘者,惯用的暖场问题是“您在工作中使用过STL的哪些组件?用过Boost的哪些组件?”,我得到的答案大多为vector、map和shared_ptr。如果对方是在校学生,我一般会问他vector或map的内部实现、各种操作的复杂度,以及迭代器失效的可能场景。如果对方是有经验的程序员,我会追问shared_ptr的线程安全性、循环引用的后果及如何避免、weak_ptr的作用等。如果对方回答得不错,还可以进一步问问他如何实现线程安全的引用计数,如何定制删除动作等。这些问题能让我迅速判别对方的C++水平。

我之所以在面试时问到Boost,是因为其中的许多组件确实可以用于编写可维护的产品代码。Boost包含近百个程序库,其中不乏具有工程实用价值的佳品。每个人的习惯与技术背景不一样,对Boost的取舍也不一样。就我个人的经验而言,首先,可以使用绝对无害的库,如noncopyable、scoped_ptr、static_assert等,学习和使用这些库比较简单。其次,有些功能很容易自己实现,正好Boost里提供了现成的代码,那就不妨一用,如date_time和circular_buffer等。然后,在新项目中,进行消息传递和资源管理可以考虑采用更加现代的方式,如在某些情况下用function/bind代替虚函数作为库的回调接口、借助shared_ptr实现线程安全的对象回调等,这二者会影响整个程序的设计思路与风格,需要通盘考虑,如果能正确使用智能指针,那么在现代C++程序里一般不需要出现delete语句。最后,应对某些性能不佳的库保持警惕,如lexical_cast。总之,在每个项目组成员都能理解并运用的基础上,适当引入现成的Boost组件,可以减少重复劳动,提高生产力。

Boost是一个宝库,其中既有可以直接拿来用的代码,也有值得借鉴的设计思路。试举一例:正则表达式库regex对线程安全的处理。

早期的RegEx类不是线程安全的,它把正则表达式和匹配动作放到了一个类里边。由于有可变数据,所以RegEx类的对象不能跨线程使用。如今的RegEx类明确地区分了不可变(immutable)数据与可变(mutable)数据,前者可以安全地跨线程共享,后者则不行。例如,正则表达式本身(basic_regex)与一次匹配的结果(match_results)是不可变的;而匹配动作本身(match_regex)涉及状态更新,它是可变的,于是要用可重入的函数将其封装起来,避免这些数据泄露给别的线程。正是由于做了这样合理的区分,所以在正常使用RegEx类时就不必加锁。

Donald Knuth在Coders at Work一书里表达了这样一个观点:如果程序员的工作就是摆弄参数去调用现成的库,而程序员不知道这些库是如何实现的,那么这份职业就没啥乐趣可言。换句话说,固然我们强调在工作中不要重新发明轮子,但是作为一个合格的程序员,应该具备自制轮子的能力,非不能也,是不为也。

C/C++语言的一大特点是其标准库可以用语言自身实现。C标准库的strlen、strcpy、strcmp系列函数是教学与练习的好题材,C++标准库的complex、string、vector则是类、资源管理、模板编程的绝佳示范。在深入了解STL的实现之后,运用STL自然手到擒来,并能自动避免一些错误和低效的用法。

为了消除使用Boost时的疑虑,用得更顺手,有时我们需要适当了解其内部实现,甚至编写简化版Boost以进行对比验证。但是由于Boost代码用到了日常应用程序开发中不常见的高级语法和技巧,并且为了跨多个平台和编译器大量使用了预处理宏,所以阅读Boost源码并不轻松,需要使用者下一番功夫。如果使用者沉迷于这些有趣的底层细节而忘了原本要解决什么问题,恐怕就舍本逐末了。

Boost中的很多库是按泛型编程的范式来设计的,对于熟悉面向对象编程的人而言,或许面临一个思路的转变。例如,你需要熟悉泛型编程的那套术语,如concept、model、refinement,才容易读懂Boost.Threads文档中关于各种锁的描述。我想,对于熟悉STL设计理念的人而言,这不是什么大问题。

在某些领域,Boost不是唯一的选择,也不一定是最好的选择。例如,要生成公式化的源代码,我会首选用脚本语言写一小段代码生成程序,而不用Boost.Preprocessor;要在C++程序中嵌入领域特定语言,我会首选Lua或其他语言解释器,而不用Boost.Proto;要用C++程序解析上下文无关文法,我会首选用ANTLR来定义词法与语法规则并生成解析器(parser),而不用Boost.Spirit。总之,使用Boost时心态要平和,别较劲去改造C++语言,把Boost有助于提高生产力的那部分功能充分发挥出来,让项目从中受益才是关键。

要学习Boost,除了阅读其官方网站的文档、示例与源码,最好能在手边放一本比较全面的中文书,以随时翻阅。对不谙英文的开发者而言,这更是可幸之至。您手上这本《Boost程序库完全开发指南》就是很好的使用指南与参考手册,在这本书中,作者由浅入深地介绍了Boost的大部分常用内容,能让读者迅速了解Boost,并从中找到自己需要的部分。拿到这本书之后,我有粗有细地阅读了一遍,总体来看,作者水平很高,也相当务实,作者对C++和Boost的理解与运用很到位,我从这本书中学到了不少新知识。为此,我乐于向希望学习Boost程序库的开发者推荐这本靠谱的书。

须知“功不唐捐”,作为一名现代C++程序员,在Boost上投入的精力定能获得回报。

陈硕

《代码大全》译者之一

中国香港