自上世纪 80 年代推出以来,C++ 的流行程度在这些年里不断变化。诸如 Java 和 C#之类托管语言的兴起,以及如 JavaScript、Python 和 Ruby 这样的脚本语言的出现,都对 C++ 的应用有所影响。但许多支持者喜欢 C++ 提供的可控性、底层能力和运行速度。C++11 承诺以更高效的方式将这些优势带给程序员,C++11 引入的那些变化也说明了在过去三十年中这门编程语言有了多大的成长。想要学习 C++11 或初次尝试 C++ 的程序员,建议阅读 Stanley B. Lippman、Josée Lajoie 和 Barbara E. Moo 编写的《C++ Primer》第五版。InfoQ 有机会采访了 Moo 女士,对她的新书和 C++ 编程语言进行了整体性的讨论。
InfoQ:让我们从你的新书的教学方式开始。你曾经参与编写的《Accelerated C++》使用了一种围绕 C++ 标准库进行教学的方式。《C++ Primer》第五版延续了这种风格。与之相比,第三版的作者采用的方法完全不同(当时是在 C 的基础上介绍 C++)。之所以提到这个话题,是因为我认为它对于讨论这门编程语言整体教学哲学的转变以及引入 C++ 11 所需要的变化,都是非常有帮助的。那么你和新团队是如何共同参与这个项目的?
Barbara:谢谢。实际上正是由于《Accelerated C++》的成功,促使 Addison-Wesley 出版社邀请我参与了《C++ Primer》第四版的工作。它在 C++ 社区中实际上扮演了非常重要的角色。自 1989 年首次出版以来,它几乎成为严肃的程序员学习 C++ 的必读之作。
《C++ Primer》的前三版是受这门编程语言变革的驱动而推出的。1998 年出版的第三版专注于当年的 C++ 标准。该版本在新标准库广泛应用之前出版,也早于《Accelerated C++》。而后者证明了与编程语言一起讲授库而非将库作为高级主题的优势。与之前的《C++ Primer》版本不同,第四版的主要动机是修改其教学策略。我们决定使用与《Accelerated C++》相同的教学方式,并特意在书的一开始就引入了库的内容。
遗憾的是,太多的 C++ 书籍仍旧基于数组和指针来讲授底层设施,而将库作为高级主题。但实际上使用数组和指针更容易出错,也更难理解。更糟的是,为了简化数组的使用,许多书都带来了一些不良习惯,例如教大家使用固定长度的数组。
使用 string 和 vector 类型使得编写程序变得更简单。因此在《C++ Primer》中很早就出现了这部分内容。当新的 C++11 标准接近完成时,我们决定使用同样的策略来展现新特性。我们彻底修订了本书,以期将这门编程语言作为一个整体来展现,而不是仅仅将新特性作为高级主题嫁接在旧有的编程语言上。C++11 的一些新特性,特别是 auto 和 decltype,以范围为基础的 for 循环语句,以及使编程更轻松的智能指针等,这些特性是与其他基础内容一起来讲授的。
InfoQ:在 C++ 的新特性中,你最喜欢哪些?
Barbara:好吧,其实我认为在上一个问题中我已经部分回答了这个问题。新的 auto 和 decltype 类型说明符允许程序员享受静态类型的好处(在编译阶段捕捉错误)而无需编写长且复杂的类型声明或搜索程序以确定需要哪个类型。
智能指针令动态内存的使用变得更简单、更安全,但我认为智能指针带来的最大价值是,在使用它编写管理资源的类时会更便捷。那些使用智能指针(取代了传统指针的位置)的类无需定义赋值运算符、拷贝构造函数和析构函数。这意味着我们可以编写相当复杂的类而无需学习拷贝控制。
其他一些我喜欢的特性,包括新的库设施,它们可用于与函数结合的编程,例如标准库函数 bind 和 function。这些新设施使用起来更干净和统一。此外,可被视作轻量级函数的 lambda 表达式,让我们可以更容易地应用和定制标准算法的行为。
一个非常重要的改变是右值引用和 move 语意,许多开发者可能并未注意,但无论如何会享受到它带来的好处。能够 move 而不是 copy 一个对象,仅是有些类会有这种需要。在实践中,我怀疑只有非常老道的程序员会直接编写 move 操作。尽管如此,在能够移动对象时避免拷贝,能够为标准库容器和字串类带来非常大的性能提升。
InfoQ:新标准是否遗漏了什么重要内容?
Barbara: 没有。委员会已经有了 Concepts 的草案,该特性试图向语言中添加约束检查,不过在正式标准中被去掉了。我觉得这种选择没什么问题,因为其设计的确还没有准备好。
InfoQ:考虑到时下热门的一些领域(移动 /Web/ 云),你觉得 C++ 是否还能适应当今软件开发世界的需求?现在有相当多的、热度不同的编程语言(Python/C#和 Java/Go 等),当开启新项目时,你觉得 C++ 与它们相比如何?(或者说,选择 C++ 11 只是为了支持 C++ 遗留代码吗?)
Barbara: 这些语言各不相同,它们与 C++ 相比在很多重要方面都有差异,包括技术性和非技术性问题。除了我不太熟悉的 Go,这些语言与 C++ 有很大不同,而且它们面向的是不同类型的应用。如果要编写一个大规模应用,并且对性能、可移植性、硬件接口或伸缩性需求都有严格的要求,那么这些语言都不合适。另一方面,如果要编写一个主要与用户交互的应用,那么我大概会考虑其中的一门语言。
对于移动 / 网络 / 云计算相关的特定问题,C++ 同样适合开发这些应用。C++ 可以用于管理服务器(云端)的计算。此外,它当然也可以用于控制移动设备自身的操作系统。所以,即使在计算机产业的最新部分,C++ 仍旧有广泛的用途。
C++、Python 以及 Java(程度较小),与 C#、Go 和 Objective-C 等语言相比还有一个很重要的不同。第一组语言的演进过程是开放的(Java 至少是部分开放的)。因此它们适用于很多平台。而第二组却并非如此。这些语言由特定的赞助公司控制。微软期望 C#成为跨平台语言,但实际上它仅用于运行在微软操作系统上的项目。迄今为止 Go 是 Google 的语言,而 Objective-C 在苹果的 iOS 应用之外用处不大。如果要编写绑定于某个平台的语言,这样的语言是合适的。如果不是这样,你必须考虑当需要支持其他硬件或操作系统时会出现什么情况。 **
InfoQ: 有人将 C++ 描述为三个独立的语言:没有作用域概念的 C 预处理器,C++ 运行时语言,以及 C++ 编译时语言—— 即模板。你是否认可这种分法?如果是这样,这个问题是不是很严重?
Barbara: 不,我认为这夸大其词了。确实存在预处理器,而且它确实与 C++ 语言本身是分离的。但除了#include 和条件编译外,自从上世纪 80 年代中期 C++ 拥有了内联和常量后,几乎没什么理由在 C++ 中继续使用预处理器了。因此,大部分 C++ 程序员甚至无需考虑预处理器,也无需熟悉其额外功能。
至于“运行时”和“编译时”语言的区别,我认为相对于程序员,它对语言的设计者和实现者更重要。抛开那些使用模板元编程的少数 C++ 程序员,很多 C++ 程序员,也可能是大部分 C++ 程序员,在使用模板或语言的其他部分时,从没考虑过二者的区别。关于模板,他们所看到的区别顶多是到编译后期才有可能见到报错。 乍看上去让人惊讶,但这并不是很严重的问题。对使用模板的程序而言,更加严重的问题是编译器报错信息的水平。
InfoQ: 对于使用 C++ 的一些争议在于其冗长的编译时间和模糊的编译错误。你认为这是否是一个实实在在需要克服的阻碍,还是说这一现象只是被夸大了?(假若这样,使用确实存在一些挑战,但付出这些代价仍然是值得的,对吗?)
Barbara: 关于编译时间,我认为,与今天相比它在过去曾经是个很严重的问题。与其它很多软件系统一样,随着机器性能的提升,编译时间已经变短了。想想看,自从上世纪 80 年代中期我们开始使用 C++ 以来,机器性能已经提升了大约 1000 倍。系统却并没有变大 1000 倍,所以与当年 C++ 缓慢的编译时间相比,编译速度在今天而言已经非常非常快了。当然,那些编写超大规模系统的团队仍需要注意如何组织代码,以缩短编译时间。遗憾的是,我认为编译时间慢对大型项目而言是无法改变的事实。
至于模糊的编译错误,我觉得主要与涉及模板的代码有关。我希望编译器的作者们能够在模板相关的报错信息上多花一些功夫,报错时使用代码中的名字而非内部生成的名字。我主要使用了 GCC 编译器来测试书中的代码,必须承认,与使用模板的代码相关的错误信息能够帮助我定位到出错的那一行,但往往无助于找出错误原因。
InfoQ: 自从我们上一次对话以来,微软和其他组织宣布了标准 C++ 基金会。你觉得对 C++ 的应用有何影响?他们以提供一个集中的 C++ 地点和更短的新标准发布周期为目标,对此你怎么看?
Barbara: 我目前还不是非常了解标准 C++ 基金会,当然他们也刚刚启动。我为这样的努力喝彩,目前看来它会是一个有趣的、值得跟踪的站点。
关于访谈对象
Barbara E. Moo是一个在软件领域具有 20 年经验的独立咨询顾问。在 AT&T 接近十五年的工作经历中,她开发了第一个使用 C++ 编写的商业产品,负责管理了公司的第一个 C++ 编译器项目,并指导了 AT&T 屡获殊荣的 WorldNet 网络服务业务的开发。
查看英文原文: Learning Modern C++: An Interview with Barbara Moo
感谢臧秀涛对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。
评论