现代C++是什么?

36

我有时会读一些关于C ++好坏的讨论,有时一个论点是今天的现代C ++与旧的C ++非常不同。我想知道具体的区别是什么?什么是“现代”C ++的例子,以及这个“旧”的C ++的例子(最好做相同的事情)是什么?


4
没有实际的引用或参考资料,很难确定你在说什么。你能提供一个链接或参考资料,以便我们知道你读了什么吗? - S.Lott
5个回答

44

广泛使用标准库和STL,异常处理和模板——而不仅仅是C++中的类


@Martin Beckett STL 是标准库的一部分。 - There is nothing we can do
2
@A-ha,STL通常被用作非正式的方式来指代标准库中的“新”部分。 - Mark Ransom
6
我也会将RAII添加到列表中。 - Mark Ransom
1
@A-ha STL 是/不是标准库似乎总是让这里的学究们感到不安。重点是新的 C++ 是 stringstream,旧的 C++ 是 printf()! - Martin Beckett
1
@Martin,在编程行业里,严谨是一种非常积极的特质。如果有人粗心大意,那就帮不了忙。你只是犯了一个形式上的错误,我来纠正一下而已。当你说:“新的C ++是stringstream,旧的C ++是printf()”时,这只是一个被抓住的孩子的很便宜的借口。虽然没有必要用感叹号(这是一个可怕的暴露你被激怒了的信号)。 - There is nothing we can do
@Mark Ransom 在解释一些非常具体的概念时,最好不要使用那些有时会被那些并不确定自己在说什么的人所使用的“非正式”方式。要坚持事实。 - There is nothing we can do

37

"现代化"的C++ 不害怕使用以下任何一个或全部:

  • RAII
  • 标准库容器和算法
  • 模板
  • 元编程
  • 异常
  • Boost 库

"旧式"的C++ 由于认为缺乏编译器支持或运行时性能不佳,往往避免使用这些东西。相反,你会发现...

  • 大量使用 newdelete
  • 手写链表和其他数据结构
  • 返回码作为错误处理机制
  • 成千上万的自定义字符串类,而不是使用 std::string

与所有的“这个 vs 那个”的争议一样,这两种方法都有其优点。现代化的C++并不是普遍更好。例如,在嵌入式环境中,通常需要额外的限制,大多数人从未需要过,因此你会在那里看到很多旧式代码。然而总体而言,我认为你会发现大多数现代特性值得经常使用。摩尔定律和编译器的改进已经解决了大部分避免使用新功能的原因。


1
我认为,不幸的是,现代C++并不害怕异常。并不是说我不喜欢异常,只是人们滥用它们... - Matthieu M.
@Matthieu,不幸的是,更多的程序员并不害怕它们,而他们应该害怕。瑞蒙德·陈(Microsoft)难道不曾声称自己不够聪明以使用它们吗? - Michael Kristofik
2
我认为他这么做是为了震惊 :) 但是异常确实会在代码中引入跳转,使得跟踪执行路径变得困难,特别是因为这些跳转是隐藏的。如果仅保留用于真正异常条件,那就没问题,但如果任何调用运算符可能失败,那你将面临一堆麻烦(维护方面)。最近我已经决定尽可能无异常编程。毕竟,“查找”方法找不到结果是正常的。 - Matthieu M.
异常只是将复杂性移动到其他地方:它们使得正常操作代码看起来简单,但是通过将执行异常处理的代码与导致问题的代码分离,使得异常处理更加复杂。如果没有一个良好的异常代码/对象,在异常处理程序中很难弄清楚发生了什么,并且通常你也不会得到这样的信息。传统的返回代码式错误传播使主线代码难以阅读,而异常处理就在有问题的代码旁边。实际上,异常只是另一种被过分吹捧的goto。 - Britton Kerin

21

一个非常明显的区别是,在“旧式”C++中,你会看到许多对象手动使用new创建,使用delete销毁。在现代C++中,只要可能,对象就会在堆栈上创建,或者至少被包装在某种智能指针中。

另一个区别是,旧式C++更注重OOP,而现代C++使用混合编程风格:过程化、模块化、面向对象和泛型。自由函数在现代C++中被认为是一件好事,而在旧式C++中它们将被塞入某个类中。

其他明显的区别包括使用已经成熟稳定且可用于生产代码的构造和库:模板、异常、命名空间、STL等。


14

C++ 中有很多被视为“现代”的东西。

首先,我认为最令人惊异的是模板的出现。不仅是 STL 本身,还包括一些不太“规则”的模板使用,这些使用导致了模板元编程的发展。例如,在即将发布的标准中就可以看到 enable_if 的存在。

我认为这是一种追求通过构造来强制正确性的 C++ 程序员运动中最显著的特点:

  • 优先选用编译器错误而不是运行时错误 > 模板 / 类型安全而非省略号 / void*
  • 使用作用域绑定资源管理(也称 RAII,但更加明确)

这种高质量的研究也导致了普遍使用以下内容:

  • STL(经过全面测试的算法和数据结构,尽管 STL 的设计相当不安全)
  • Boost 库(由专业程序员审查,几乎没有漏洞,高度可移植)

对这些库的评估还证明了 C++ 程序员不再对那些面向对象语言有自卑感:现在我们从这种情况中解放出来,毫不犹豫地混合使用各种范式(面向对象、泛型、过程式)来实现我们的目标。

总的来说,我认为现代 C++ 更多的是一种心态。我们(C++ 程序员)试图摆脱那些长期以来困扰着我们的可怕的未定义行为,并试图让用户也避免这种情况(通过定义不允许出现这种情况的接口)。我们还接受了别人已经先行一步的事实,并且重新利用现有的库并不意味着软弱。


1
更令人惊讶的是,模板从未被用于它们现在的用途。这并不像Stroustrup一开始就打算创建一个在编译时执行的图灵完备子语言。 - Michael Kristofik
@Kristo:我同意,人们偶然发现它们形成了一个图灵完备的语言,而且我仍在每个月发现新的有趣用法(不是我自己发现的:p 我确实读了很多)。更有趣的是,由于C++类型的固有不可变性,它们引入了函数式编程习惯。 :) - Matthieu M.

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接