“全团队” C ++功能?


16

在C ++中,异常之类的功能会影响整个程序:您可以在整个程序中禁用它们,或者需要在整个代码中对其进行处理。正如有关C ++ Report著名 文章所述

与直觉相反,编码异常的困难部分不是显式的抛出和捕获。使用异常的真正困难部分是编写所有中间代码,以使任意异常可以从其抛出站点传播到其处理程序,安全地到达并且不会破坏程序的其他部分。

由于甚至new抛出异常,因此每个函数都需要提供基本的异常安全性 -除非它仅调用保证不抛出异常的函数- 除非您在整个项目中完全禁用异常

因此,异常是“整个程序”或“整个团队”的功能,因为使用它们的团队中的每个人都必须理解它们。据我所知,并不是所有的C ++功能都像那样。

一个可能的例子是,如果我没有模板但不使用它们,我仍然可以编写正确的C ++,或者我不会吗?我什至可以调用sort整数数组,并享受其惊人的速度优势。C qsort(因为未调用任何函数指针),而又不会冒bug的风险-是否?看来模板不是“全团队”。

是否还有其他C ++功能会影响代码而不直接使用它们,因此是“整个团队”?我对C中没有的功能特别感兴趣。

更新:我特别要寻找的功能是没有需要您注意的语言标记。我得到的第一个答案是const-正确性,它也是一个完整的团队,因此每个人都需要学习它。但是,AFAICS仅在调用标记为的函数时才会对您产生影响const,并且编译器将阻止您在非const对象上调用它,因此您可以向Google寻求帮助。除非有例外,否则您什至没有得到。而且,它们总是在您使用后立即使用new,因此异常更加“阴险”。但是,由于我不能客观地表述这一点,因此我将不胜感激任何全团队功能。

更新2:我应该写一些类似“ C ++特定功能”的文章,而不是C ++功能,以排除适用于大量主流编程语言的多线程之类的东西。

附录:为什么这个问题是客观的(如果您想知道的话)

C ++是一种复杂的语言,因此许多项目或编码指南都试图选择“简单的” C ++功能,并且许多人尝试根据大多数主观标准来包括或排除某些功能。有关此问题,请按此定期关闭。

相反,在上面,我(尽可能精确地)定义了“整体”语言功能是什么,提供了一个示例(例外),以及有关C ++文献的大量支持证据,并要求使用C ++的整体团队功能毫无例外。

您是否应该使用“整个团队”功能,或者是否使用相关概念可能是主观的,但这仅意味着该问题的重要性像往常一样是主观的。

Answers:


11

我将并发作为“整个团队”功能。

尽管可以对软件进行设计,使得只有很少的专家需要了解并发问题,并且团队的其他成员可以在不担心复杂性的情况下获得收益(就像您可以使用模板一样),但实际上它确实不能那样工作。实际上,如果您有多个线程,那么如果使用该变量存在潜在的并发问题,则必须仔细分析所使用的每个变量。


我同意线程是整个团队的功能,尽管它们不是特定于C ++的。但是,还有其他一些用于并发的接口(不是基于线程的接口),主要是其他语言,并且有一些接口允许并发更好地封装(尽管这仍然是编程语言中的当前研究主题)。因此,这是否适用于并发本身是一个悬而未决的问题。
Blaisorblade

@Blaisorblade-C ++ 11引入了它自己的线程库,因此,它现在是C ++的一部分。
Michael Kohne

@MichaelKohne:我并不是说C ++不支持多线程。我说线程不是特定于C ++的,因为许多其他语言都具有线程。我刚刚注意到,所描述的问题适用于线程作为并发的接口。
Blaisorblade

对于这个核心问题,我会说“竞赛条件”是一个更好的词。也就是说,程序员可能根本不需要研究或使用并发框架,但是如果他们编写任何C ++代码,并且可能从多个线程中调用它们的代码,那么他们通常需要考虑竞争条件,在他们编写的所有代码中。
rwong

这让我想起了几年前与同事的沟通不畅。一位同事问另一个同事:这个(某些函数)线程安全吗?另一个同事回答是。然后提出要求的同事继续在多个线程中使用它,并得到了意外的结果(它没有崩溃,但是对同一对象执行了多次操作)。原来,问这个问题的同事并没有“线程安全”的含义的思维模式,并且误以为“我可以做我想做的事”。
rwong

10

显而易见的答案是const正确性:由于const/ volatile限定性具有传染性,因此一旦代码的一部分开始使用它,则每个(直接或间接)调用代码也必须const正确,或者const明确地丢弃它。

但是,与例外一样,这显然最终是一件好事。甚至更是如此,因为与异常安全不同,它由编译器严格验证。


2
此外,const-correctness是透明的:它仅与您赋予函数的类型(始终可见)有关,如果您弄错了,编译器会大喊大叫。我在想更多不透明的东西,在此之前你不知道出了什么问题,直到为时已晚(即使那样,也很难弄清楚)。但是您的答案仍然很有趣,因此被否决了。
Blaisorblade 2013年

10

指针。

  • 指针是否指向堆栈上的内存?
  • 指针是否指向堆上的内存?
  • 指针是否指向单个对象?
  • 指针是否指向数组?
  • 指针是否指向数组中间的位置?
  • 指针有效吗?
  • 指针被扭曲了吗?
  • 什么代码“拥有”指针?
  • 是否应该手动释放引用的对象?如果可以,怎么办?

1
+1是专门因为有关指针所有权的问题。如果没有智能指针,所有权确实会在整个团队中传播。
2013年

3

另一种可能是操作员超载。一旦代码库中的一部分开始鼓捣运算符重载大家往往开始的第二个猜测只是究竟是什么任何给定对象,他们与工作实际做的事情。它不会像异常和const正确性那样在代码库中进行显式传播,但是如果整个团队不在何时,如何以及为什么使用同一个页面上,那肯定会引发问题。


1

除了const正确性(如上所示)之外,我想到的唯一一个就是流状态。如果您在使用对象和子对象以及对象层次结构的地方编写C ++代码,则最终将需要向程序操作员发送数据或从程序操作员接收数据。你可以写简单的流媒体业务是编译和是语义正确的?

std::ostream& operator<< (std::ostream&, MyClass const&) {...}
std::istream& operator>> (std::istream&, MyClass&) {...}

...但是一旦您这样做,您将永远无法保证您尝试编写(或最重要的是读取)的内容与客户端向您发送的内容采用相同的格式。流有太多奇怪的情况发生,更糟的是,如果您必须在函数调用链中传递流或流标志作为参数,这通常是类流的实现。因此,就像您使用上面的术语一样,流可以定义为“阴险”,甚至可以定义为“病毒”(尽管在任何地方都无法达到const-correctness的程度)。

有一个成员深入您的类层次结构string吗?意外的是,客户端发送好一个词,否则后果不堪设想。您要序列化一些数字吗?最好在每个函数调用深度检查,保存和还原流标志,因为在调用函数之前,您永远不知道谁是白痴,只是将其流设置为八进制输出。或者更糟的是-谁刚打电话像setfillsetw,从而打破了输入/输出的第一-and的格式只有您的第一代会员积分,因为这些国家不传播。哦,让我们不要问有关流和国际化的问题。

有一个在任何你正在流以正确的方式,或以错误的方式,甚至流的语言没有警告所有。要求客户端代码传递要写入数据备份的流?您真的没有办法知道流指向/dev/null。(另一方面,您可以通过这种方式获得令人难以置信的备份速度和压缩率!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.