为什么 std::exception 会在 std::bad_alloc 之前捕获我的异常

Why does std::exception catch my exception before std::bad_alloc?

本文关键字:std 异常 我的 exception 会在 bad 为什么 alloc      更新时间:2023-10-16

问题:我同时使用std::exception和std::bad_alloc来捕获异常。我正在使用的尝试捕获的顺序有问题。我附上了示例代码以供参考。

预期:如果我的错误bad_alloc则抛出bad_alloc异常。

已观察:我的错误bad_alloc,但抛出异常。

示例代码

#include "stdafx.h"
#include <iostream>
#include <exception>
using namespace std;
void goesWrong()
{
    bool error1Detected = true;
    bool error2Detected = false;
    if (error1Detected)
    {
        throw bad_alloc();
    }
    if (error2Detected)
    {
         throw exception();
    }
}
int main()
{
    try
    {
        goesWrong();
    }
    catch (exception &e)
    {
        cout << "Catching exception: " << e.what() << endl;
    } 
    catch (bad_alloc &e)
    {
        cout << "Catching bad_alloc: " << e.what() << endl;
    }
    return 0;
}

关于它们的继承关系,您必须以相反的顺序排列异常。std::exceptionstd::bad_alloc 的父类,这就是为什么它之前在 catch 列表中找到的原因。因此,您必须将代码转换为:

   try {
      goesWrong();
   }
   catch (bad_alloc &e)
   {
      cout << "Catching bad_alloc: " << e.what() << endl;
   }
   catch (exception &e)
   {
      cout << "Catching exception: " << e.what() << endl;
   }

你不仅限于捕获对象:你可以抛出整数,字符......随便什么。在这种情况下,catch(...)是捕获它们的唯一安全方法。

也就是说,使用标准类库中的对象是建议的方法。在这种情况下,由于 std::exception 是所有(标准(异常的基类,它将捕获抛出的所有可能的异常。

您可以创建自己的异常类,从 std::exceptionstd::runtime_error 派生它们,例如,我的个人选择。

希望这有帮助。

在C++中,在将处理程序与异常匹配时,会考虑异常处理程序的列出顺序。将调用第一个可以处理异常的处理程序,即使列表下方有更好的匹配项。这与 Java 或 C# 不同,在 Java 或 C# 中,只会调用最佳匹配项(编译器会强制您将其放在列表顶部(。

由于异常是通过引用传递的,因此应用多态性;这意味着可以将子类传递给期望其父类的处理程序。由于 std::bad_allocstd::exception 的子类,因此它将由第一个 catch 块处理。

要获得预期的行为,请将捕获块反向放置:

catch (bad_alloc &e)
{
   cout << "Catching bad_alloc: " << e.what() << endl;
}
catch (exception &e)
{
   cout << "Catching exception: " << e.what() << endl;
}

这样,std::bad_alloc 将匹配第一个处理程序,而 std::exception 及其所有其他子类将匹配第二个处理程序。