【问题标题】:c++ - Throwing multiple exceptions of the same typec++ - 抛出相同类型的多个异常
【发布时间】:2016-02-21 20:57:17
【问题描述】:

所以我有一个程序有两个例外。在这两种情况下,我都想抛出一个可以在主函数中捕获并在错误消息中使用的字符串。但是,据我对他们的了解

    try {
     ...
    } catch(string msg) {
     cerr << "..." << msg << "..." << endl;
    } catch (string msg2) {
     cerr << "..." << msg2 << "..." << endl;
    }

不允许。有什么办法可以做上述或类似的事情吗? 谢谢

【问题讨论】:

  • 你希望它做什么?用例是什么?
  • 对不起,我不知道用例是什么。我想要做的是,我的程序可能会根据用户输入遇到两个大错误。在这两种情况下,我都有不同的信息要打印出来。因此,我希望每个异常都能捕获不同的消息。有没有办法识别这两个字符串异常?
  • 你熟悉if-statements吗?
  • 是否有正当理由不能抛出异常并正确设置其 what 参数而不是抛出字符串?
  • 抛出不继承自 std::exception 的东西是非常不友好的。如果您定义了两个这样做的不同类继承,那么您可以轻松地捕获它们 - 一个捕获两个捕获,或者每个捕获单独捕获,视情况而定。

标签: c++ exception


【解决方案1】:

我看到两个用例:

1。您需要两种不同类型的错误。

添加派生自std::exception的异常类

class MyException1 : public std::exception
{
  std::string message;
public:
  MyException1(std::string const &what_arg) : message(what_arg) {}
  MyException1(char const * what_arg) : message(what_arg) {}
  const char* what() const { return message.c_str(); }
};

class MyException2 : public std::exception
{
  std::string message;
public:
  MyException2(std::string const &what_arg) : message(what_arg) {}
  MyException2(char const * what_arg) : message(what_arg) {}
  const char* what() const { return message.c_str(); }
};

并抓住那些:

try
{

  int a = 5;

  // do stuff

  if (a == 7)
  {
    throw MyException1("Error 1 occured in  because a == 7.");
  }
  else if (a == 5)
  {
    throw MyException1("Error 1 occured because a == 5.");
  }

  // do more stuff

  if (a == 22)
  {
    throw MyException2("Error 2 occured in  because a == 22.");
  }
  else if (a == 575)
  {
    throw MyException2("Error 2 occured because a == 575.");
  }

}
catch (MyException1 &ex)
{
  std::cout << "Exception 1: " << ex.what() << "\n";
}
catch (MyException2 &ex)
{
  std::cout << "Exception 2: " << ex.what() << "\n";
}

注意:这是自定义异常的简单但不是最佳设计,因为std::string 可能会抛出并且您的程序将被终止。

2。您需要两条不同的错误消息:

使用来自&lt;stdexcept&gt; 标头的适当类型的异常:

try
{

  int a = 5;
  // do stuff
  if (a == 7)
  {
    throw std::runtime_error("Error 1 occured because a == 7.");
  }
  else if (a == 5)
  {
    throw std::runtime_error("Error 2 occured because a == 5.");
  }

}
catch (const std::exception &ex)
{
  std::cout << "Exception: " << ex.what() << "\n";
}

注意:如果唯一期望的行为是不同的输出,则可以在没有自己的类型的情况 2 中模拟案例 1 的行为:

try
{

  int a = 5;
  // do stuff
  if (a == 7)
  {
    throw std::runtime_error("Exception 1: Error 1 occured in  because a == 7.");
  }
  else if (a == 5)
  {
    throw std::runtime_error("Exception 1: Error 1 occured because a == 5.");
  }
  // do more stuff
  if (a == 22)
  {
    throw std::runtime_error("Exception 2: Error 2 occured in  because a == 22.");
  }
  else if (a == 575)
  {
    throw std::runtime_error("Exception 2: Error 2 occured because a == 575.");
  }

}
catch (const std::exception &ex)
{
  std::cout << ex.what() << "\n";
}

【讨论】:

    【解决方案2】:

    使用std::runtime_error 它有一个接受字符串的构造函数。因此,当它被抛出时,传递一个不同的值。

     throw runtime_error( "msg1");
    
     ...
    
     throw runtime_error("msg2");
    

    然后,当您捕获时,只需在对象中打印消息

     ...
     catch( exception& e ){
         cout << e.what() << endl;
     }
    

    【讨论】:

    • 这似乎与抛出 std::string 相同,因为如果不分析字符串文本就无法区分两个异常。
    • 您希望避免抛出字符串,因为它们也可能抛出异常。如果您必须立即处理异常,那么您的程序会崩溃。抛出运行时错误是清楚且更惯用的正确方法。如您所见,它是通过对 excetipn 的引用而引起的。字符串不会从异常继承,也不会在那里出现。为了正确地将您的代码与其他人集成,任何抛出的对象都应该从 std::exception 继承。 stackoverflow.com/questions/134569/…
    【解决方案3】:

    第一个:您的编译器应该为此发出警告,因为第二个catch 永远不会被执行,因为它们具有精确的签名。此外,您不能在第一个异常处于活动状态时引发第二个异常(在堆栈展开期间引发尚未进入 catch 块的异常),否则运行时将终止您的程序。

    其次:更喜欢通过引用来捕获异常

    第三:希望你的异常对象落入std::exception的继承树中。

    最后:你到底想做什么?

    【讨论】:

    • 此外,当第一个异常处于活动状态时,您不能引发第二个异常,否则,运行时将终止您的程序。 - 这听起来不正确,但我'不知道你想说什么。您当然可以从 catch 块中抛出异常。您不能做的是在由throw 引起的堆栈展开期间从析构函数中抛出异常。
    • 这主要是我想说的。谢谢,让我更正我的答案以澄清
    猜你喜欢
    • 2016-11-10
    • 2013-08-17
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    相关资源
    最近更新 更多