c++ - 为无异常数组寻找一个好的解决方案

标签 c++ arrays exception

如果我没记错的话,std::array/vector 都会抛出异常。 有可能消除它吗? 例如,我知道我可以将 nothrow 添加到 new 中,这样它就不会抛出异常,只返回 null。

我需要使用某种类型的数组,我更喜欢一些 std 版本而不是 new[] 版本,但不想涉及异常。 你能推荐一个好的选择吗?

最佳答案

从技术上讲,除了斯诺曼在已删除答案的评论中提出的“不可能”之外,还不能回答原始问题。然而,我确实希望我能提供一些解决方案的建议,以及“无异常(exception)”政策背后的哲学和思想,这可以用来争论使用std::vector。作为一件好事,而不是一件可以避免的事情。显然,由读者来决定这样的论点是否可能为读者个人和项目带来积极或不那么积极的结果。

编码标准中“无异常(exception)”规则的目的通常是为了避免相当困惑的情况,即有很多不同的异常,在不同的级别处理,并且代码变得相当难以阅读 - 它可以是很难管理,并且是“不得抛出异常”的合理理由。

如果这是目的(而不是例如“我们正在使用一个不支持异常的编译器,因为它是唯一一个支持我们需要编译的处理器 X”),那么我会争辩说使用 std::vectorstd::map仍然应该被允许,也许带有 try ... catch里面main [或类似的中心位置] 捕获所有异常并以合理的用户友好方式报告异常,然后退出 - 因为如果您遇到 std::vector 的情况,您的代码将不会“正确”抛出异常 - 内存不足或访问容器中超出范围的元素不是“正常操作”的一部分。

另请注意,如果您有严格的“无异常(exception)”规则,那么必须避免的不是 STL,而是所有对 new 的调用。 [new nothrow 除外variety] - 更多内容见下文。

还有另一种情况,异常“异常糟糕”,即从 C 调用 C++ 代码的情况——在这种情况下,异常从 C++“泄漏”到 C 代码中是未定义的行为(因为运行时在这种情况下,在堆栈中向上查找处理程序时将不知道如何处理异常。

如果规则是严格的“你不能在 C++ 中使用任何可能抛出异常的功能”,那么几乎所有的标准模板库(以及更多)都超出了范围。您必须在网上搜索其他替代方案 [抱歉,无法在此处提供任何有意义的帮助] 并编写大量如下代码:

some_vector_that_without_exceptions<int> v;
...
result = v.insert(element);
if (result != GOOD) 
    ... whatever you do when you can't insert to vector ... 
else 
    ... continue as you were ... 

我在工作中遵循“不去,不提早返回”的准则进行编程,这是有道理的,但您确实会重复很多:

result = some_thing(...);
if (result != success)
{
   ... cleanup ...
}
else 
{
    result = next_thing(...);
    if (result != success)
    {
       ... same cleanup as above ... 
       ... clean up after next_thing ... 
    }
    else
    {
        ... more stuff like above ...
    }
}

一段时间后它会变得相当乏味,但这就是有时使用编码标准的生活。

因为STL容器抛出异常的主要原因是newdelete , 根据您在系统内存不足时实际希望发生的情况,有可能编写您自己的 operator new (这里是一个简单的版本)可以解决这个问题:

void *operator new(size_t size)
{
    void *p = malloc(size);
    if (p == NULL) 
    { 
       ... do something, like report out of memory and exit ...
    }
    return p;
}

void operator delete(void *p)
{
    free(p);
}

// And similarly for new [] and delete [].

这将避免插入/调整大小的所有抛出行为,例如 std::vectorstd::map [当然,std::vector::resize仍然会有一个 throw上面的标记,因为头文件不知道您的 operator new永远不会抛出异常——但在实践中,它不会发生,这实际上是 STL 容器“在正常情况下”抛出异常的唯一原因(即,不是超出范围的访问等)。

关于c++ - 为无异常数组寻找一个好的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32320152/

相关文章:

C++ 多态性 : Is there any way to find the address of an object's member function?

c++ - 以编程方式在 Linux 上更改墙纸

java - Child[] 无法传递给接受 Parent[] 的方法。为什么?

java - 在非满数组中随机选择一个数组元素

c++ - wchar_t数据类型如何在c中工作?

c++ - Linux 上 RCF 的 boost 异常

c# - 将唯一数组元素移动到前面并对数组进行切片的最快方法

java - 如何增加 Java 堆栈跟踪转储的显示行数?

java - JOptionPane 中的文本换行?

c# - 如何分块化 IEnumerable<T>,而不会在失败时丢失/丢弃项目?