【问题标题】:How can I catch exception from different Class?如何从不同的类中捕获异常?
【发布时间】:2018-10-18 12:17:58
【问题描述】:
#include <iostream>
using namespace std;

class A{
    public:
        void func1() throw(){
            cout << "func1 throw 1\n";
            throw 1;
        }
};

class B{
    public:
        A a;
        void func2(){
            try{
                a.func1();
            }
            catch(int e){ //terminate called after throwing an instance of 'int'
                cout << "func2 catch " <<e;
            }
        }
};

int main(){
    B b;
    b.func2();
    return 0;
}

这是我的问题的简化版本... 有一个来自 A 类的函数,A::func1()。 它抛出 1;

然后是 B 类,它从 func2() 调用 A::func1()。 我做了try-catch子句来捕捉A::func1()抛出的1,从现在开始我遇到了一个问题......

当我从 main() 调用 B::func2() 时出现运行时错误 “在抛出 'int' 的实例后调用终止”。

这个问题出现在“g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609” 它在“Window 10”的“Visual Studio 2017”中正常工作!!

所以,我认为这个问题与编译器或操作系统有关。 你能解释一下我该如何解决这个问题吗?

【问题讨论】:

  • 作为建议,请使用谚语:“按价值投掷,按引用捕获”。
  • @AlgirdasPreidžius 答案在下面,伙计
  • 下次请继续简化问题,直到您拥有可以制作的最小版本。所有类的东西在这里都无关紧要。您最终会尝试删除 throw() (因为这将是剩下的最后一件事)并发现这是问题所在,导致您查看它的实际含义,就像您在编写它时应该做的那样......

标签: c++


【解决方案1】:

这与类无关,无论它们是否相同。

void func1() throw(){
  cout << "func1 throw 1\n";
  throw 1;
}

func1 上面有throw(),意思是“这个函数不会抛出异常”。

然后它抛出一个异常。

这会导致调用std::terminate,因为它是错误的。

您会在 Windows 上看到不同的行为,因为在某些模式下使用 Visual Studio 时,the result is undefined without std::terminate being called,这也是错误的。

删除throw()。

【讨论】:

  • If Visual Studio accepts this, then Visual Studio is also wrong. 为什么?
  • @user2079303 标准告诉我们应该发生什么,如果没有发生,说明编译器出错了。
  • 我同意。我想不清楚你所说的“接受这个”是什么意思。
  • 是的,在他们的 msdn 上提到他们处理 throw 有点不同。因此,如果您想要符合(最新标准)的行为,则应始终使用 noexcept:docs.microsoft.com/en-us/cpp/cpp/… 或使用 /std:c++17 开关来解决此问题。
  • @LightnessRacesinOrbit 无关紧要,因为它已被删除(throw() 很快就会被删除);P
【解决方案2】:

throw() 是 noexcept 的已弃用同义词,即您的函数永远不会抛出任何东西。
让noexcept 函数产生未处理的异常会导致立即调用std::terminate。

【讨论】:

  • throw() 不是noexcept 的直接同义词,行为实际上略有不同。从noexcept 函数传播的异常直接调用std::terminate,但是从throw() 函数传播的异常应该调用std::unexpected——这是一个可配置的处理程序,默认情况下,它委托给std::terminate。跨度>
  • @Bitwize cppreference 明确指出它是“[the] 与 noexcept(true) 相同”。
  • 它们是 C++17 的同义词。
  • @Quentin Huh,我不知道 C++17 将其更改为相同的行为!感谢您的更正,我想我的信息已经过时了。
  • @Bitwize 我的荣幸!例外对委员会来说是一条崎岖不平的道路,而且很难跟踪所有事情,我不得不检查:)
猜你喜欢
  • 1970-01-01
  • 2018-01-04
  • 2017-04-07
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多