[译] Why C++ Is Not Back

前言:这个月初,Herb Sutter 发了一篇名为 Perspective: “Why C++ Is Not ‘Back’”,的文章,虽然 Sutter 不同意原文中的全部细节,但也推荐读一读原文和评论。语言之争,由来已久,每次一有这种文章就会引发激烈的讨论,比如这里

本译文中不会发表任何观点,尽量表达原作者的意图,如有翻译不当的地方欢迎大家积极指出,我会做出修改。

原文在这里: Why C++ Is Not “Back”

下面是译文:

我喜爱 C++。

C++ 真正教会了我如何写代码。

以前,我会学习语言本身的复杂性,STL,以及内存管理和指针运算中的所有细节。

这些都是很美好的时光。我还记得一遍又一遍的读 Scott MeyersEffective C++ 系列。每一次都能从中学到一些新的东西,或者更理解如何使用 C++。

我说上面这些只是想让你知道,我不讨厌 C++。我喜欢 C++。

我知道,有很多优秀现在仍然在使用 C++ 并教别人如何使用,这一点也没有错。

但问题是什么?

新消息是不正确的

C++11 发布了,最近大家对使用 C++ 开发又提起了兴趣。

不要误会我的意思,C++11非常棒!我100%的同意新标准中所做的一切。C++ 无疑已经变得更易用也更强大。

但有一件事,它并没有做到,这是最重要的——更简单。

看来,许多经验丰富的开发人员已经忘记了当初为什么抛弃 C++ 而转到 Java,C# 以及其他的开发语言中。

许多年轻的或者新入行的开发者不知道这些历史,被现在 C++ 的新消息和复兴所迷惑。

每个人都在问我,是否需要学习 C++,就像几年前一样,我现在的答案还是一样——

好吧,大写的 “不” 是有点苛刻。一个更好的答案是 “为什么?”

你为什么想要学习 C++?

我所能想到的今天去学习 C++ 的理由只有下面三个。

  • 你绝对的需要每一 bit 都发挥出最大的性能,并且想要用一个支持面向对象抽象的语言
  • 你写的代码将跑在原生的硬件上。(比如:你正在写一个底层驱动程序)
  • 当内存控制和时间绝对重要的时候,你需要系统有确定性的行为以及手动管理内存的能力。(想想实时嵌入式操作系统正在控制的一个移动的机械装置)

虽然我可能少考虑了其他的情况,但是其他的情况基本上也无法逃出上面所说的三个范围。

等等,等等,可移植性呢?

不需要!不要想着学习 C++ 然后构建任何地方都能跑起来的软件。 今天我们还有大量的其他选择,而且 C++ 根本没有人们以为的那样有多好的可移植性。每个操作系统或者平台的底层抽象是非常不同的。

另外,请不要告诉我 C++正好可以给你你所需要的更多的权利和可控性。

大多数软件开发是解决实际问题,管理复杂性,而不是在玩底层的细节。在几乎所有的现代大型软件开发中,我们需要的都是更高级的抽象,而不是低级别的抽象。

但是,我就是想学 C++

好了,听着,我知道你认为 Windows 8 非常酷,并且有很多人都在学习 C++ 来开发他们的 Windows 8 应用,但是在你喝 “Kool-Aid” 之前,你应该知道它里面有些什么。

写 C++ 代码不是去野餐。

即使 C++11 做了一些改变,C++ 仍然是一个非常难学习,也非常难掌握的语言。

你也许听说过下面这个关于 C++ 的说法:

C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do, you blow away your whole leg!

— Bjarne Stroustrup

你不知道 Bjarne 是谁?好吧,他是 C++ 之父。我想你能从他的话里面得到自己的结论。

我不断的听到 C++11 相对于 C++98 的改进,我一点也不怀疑。

但它没有改进的是语言的规模大小——事实上反而增加了。

当然,你可以使用 C++ 的一个子集。当然,你也可以使用新的智能指针,把你从手工管理内存的情况中解救出来。你可以使用 lambda 来避免使用函数指针。当然类型自动推导也是非常必要的新鲜空气。

问题是,你仍然需要知道底层的东西,以了解当你调试一个有内存问题的 C++ 程序时,究竟问题在哪儿。(如果你生在脱管代码的时代,这些可能是你从来都没有听说过的东西。)

你也可能会遇到 20 年前的 C++ 代码,它看起来就像一个完全不同的语言。

下面是一个 C++ 开发人员的面试问题列表:

  1. C++ 中有多少种方式初始化一个基本类型数据,它们分别是什么?
  2. 为什么析构函数要声明为虚函数?
  3. C++ 支持重载,是什么意思?
  4. C++ 重载的例子有哪些?
  5. 什么是 name mangling,为什么要用它?
  6. 什么是抽象基类?
  7. 什么是 RTTI?
  8. 如何访问一个同名但是被”隐藏“的变量?
  9. namespace 是什么,如何使用?
  10. struct 与 class 有什么区别,与 C 比又有什么区别?
  11. template 是什么,如何使用?
  12. 什么是拷贝构造函数,什么时候需要拷贝构造函数,与赋值操作符相比有哪些不同?
  13. 深拷贝和浅拷贝有什么不同?
  14. const 的作用是什么,如何使用?
  15. 在 C++ 中,传值,传引用和传递指针的区别是什么?
  16. 什么时候应该返回一个值的引用,什么时候不应该返回一个值的引用?
  17. 在堆和栈上创建一个变量有什么不同?
  18. 如何释放一个数组动态分配的内存?只使用 delete 的含义是什么?
  19. 什么是多继承? 什么时候使用多继成?
  20. 什么是纯虚函数?
  21. 关键字 mutable 是做什么的?
  22. 关键字 volatile 是做什么的?
  23. STL 是什么?
  24. 什么是 vector ?
  25. 头文件 algorithms 中包含哪些内容?
  26. #include<iostream.h>#include<iostream> 有什么区别?
  27. ++ii++ 有什么区别?
  28. 什么是短路计算?怎样才能使用它?它为什么是危险的?
  29. 什么是逗号表达式?
  30. 唯一的三目运算符是什么?如何使用?
  31. const 成员函数有什么作用?如何使用?
  32. 在 C++ 中使用 try/catch 好不好?
  33. 为什么不能在析构函数中抛异常?
  34. 关键字 explicit 是做什么的?
  35. C++ 中类型转换的正确方式是什么?
  36. 内联函数是什么,都做了什么?

上面一些问题,在 C# 或 Java 中,有相同的答案,但是你可以从这个问题列表看出来,C++ 水非常非常深。需要花费大量的精力来了解语言本身。

C# 或 Java 开发会有些关于语言本身的学习,但更多的是学习库的使用。

C++ 开发更多的是学习语言的每一个角落。

C++ 不是未来的方向

最大的问题,编程语言真正需要的是简单和增加它的抽象能力,而不是降低。

底层的代码总会有需求,但是今天大部分的代码都是更高层次的。

很多年前,当我无法再说 C++ 比 C# 开发效率更高的时候,我第一次跳下了 C++ 这条船。

我很长时间都试图相信曾经在 C++ 上耗费的精力时没有白费的,但是事实证明,C# 把事情简化到了伟大的程度,它有 C++ 一样的能力,却不需要额外的责任。

当我想休息一下再写这篇博客的时候,我碰巧发现了微软研究院的一个叫做 touchdevelop 的项目。这才是我们的方向。我们需要编程语言越来越简单,而不是越来越复杂。

不要误会我的意思,touchdevelop 会有非常多的限制,但是我相信像这样的东西才是未来。

似乎微软正在努力推动让 C++ 回归主流,让 Windows 8 支持 C++ 开发,并试图干掉 XNA,但我觉得这是一个扭曲的看法,这似乎是 Windows 系统的开发人员根深蒂固的想法——开发人员想要使用 C++。

我只是不想看到自己再回到以前,在能使用 C# 在各个平台写代码的时候,还使用那么复杂的语言。C# 不是完美的语言,但是它非常优雅,简单。

关于 C++ 的只言片语

虽然我说了上面那些话,但我还是相信学习 C++ 是值得的。

不,我不是在自相矛盾,请允许我解释。

如果你能写 C++,那么你能用其他任何语言写代码。如果你了解堆、栈、内存,引用和指针以及让 C++ 如此复杂的其他底层细节,它会在你使用高级别抽象语言时给你帮助,让你能够明白计算机是如何工作的。

这篇文章,我的观点不是抨击 C++,或抨击 C++ 使用者,和教别人 C++ 的人,只是说出我的观点,这貌似是热心的 C++ 社区所鼓励的。

每个人都不会成为 C++ 开发人员,而且也不需要。也许 C++ 有能力让你的程序更高效(在某些情况下),它几乎绝对不可能让你开发过程更高效(除非极少数的极端情况下。)

我很高兴,C++ 有了很大的改进,但是我不认为它能很快的东山再起,而且这是一个好事情。

译文完。

参考

C++

Comments