注意: 我不是在这里扮演魔鬼的拥护者或类似的角色——我只是真的很好奇,因为我自己并不在这个营地。
标准库中的大多数类型要么具有可以抛出异常的变异函数(例如,如果内存分配失败),要么具有可以抛出异常的非变异函数(例如越界索引访问器)。除此之外,许多自由函数可以抛出异常(例如 operator new
和 dynamic_cast<T&>
)。
在“我们不使用异常”的背景下,您 实际上 如何处理这个问题?
您是否试图 从不 调用可以抛出的函数? (我看不出它是如何扩展的,所以如果是这种情况,我很想听听你是如何做到这一点的)
您是否同意标准库抛出并将“我们不使用异常”视为“我们从不从 我们的 代码中 抛出 异常并且我们从不从 其他 代码中 捕获 异常”?
您是否通过编译器开关完全禁用异常处理?如果是这样,标准库的异常抛出部分是如何工作的?
编辑 您的构造函数,它们会失败,还是按照惯例使用带有专用 init 函数的两步构造,该函数可以在失败时返回错误代码(构造函数不能),还是您做其他事情?
编辑 问题开始后 1 周的次要澄清……下面的评论和问题中的大部分内容都集中在例外与“其他”方面的 _原因_。我的兴趣不在于此,但是 当 您选择做“其他事情”时,您 如何 处理 会 引发异常的标准库部分?
原文由 Johann Gerell 发布,翻译遵循 CC BY-SA 4.0 许可协议
我会为我自己和我的世界一角回答。我编写了 c++14(一旦编译器有更好的支持,将是 17)延迟关键金融应用程序,处理巨额资金并且永远不会下降。规则集是:
内存是池化和预分配的,所以初始化后没有 malloc 调用。数据结构要么是不朽的,要么是可以简单复制的,因此几乎不存在析构函数(也有一些例外,例如范围保护)。基本上,我们在做 C + 类型安全 + 模板 + lambdas。当然,异常是通过编译器开关禁用的。至于 STL,它的好部分(即:算法、数字、type_traits、迭代器、原子……)都是可用的。抛出异常的部分与运行时内存分配部分和半 OO 部分很好地吻合,所以我们可以一次性摆脱所有的麻烦:流、容器,除了 std::array 和 std::string。
为什么要这样做?