为什么要按基数抛出派生类捕获?

时间:2016-09-16 09:25:28

标签: c++ exception-handling try-catch throw catch-block

对于下面的代码,结果是“EA异常完成”,这意味着虽然我们抛出它被基类捕获的派生类。它总是吗?如果是这样,我怎样才能使派生类捕获,从而出现“EB Exception Finished”?

此外,我无法确切了解throw EB()catch(EA&)的含义。 catch(EA&)是否意味着catch块获取EA object 的引用?

对不起我的无知。如果你推荐我一本关于例外结构的书或其他内容,那将是很好的帮助。

class EA {};
class EB: public EA {};

void F()
{
  throw EB();  // throw at EB().
}

int main()
{
  try
  {
    F();
  }
  catch(EA&) // caught here??
  {
    std::cout<<"EA Exception";
  }
  catch(EB&) // why not me? every time?
  {
    std::cout<<"EB Exception";
  }

  std::cout<<" Finished"<<std::endl;

  return 0;
}

5 个答案:

答案 0 :(得分:3)

更改replaceState块的顺序以修复该行为:

catch

编译器甚至会警告你:

#include <iostream>

class EA {};
class EB: public EA {};

void F()
{
  throw EB();  // throw at EB().
}

int main()
{
  try
  {
    F();
  }
  catch(EB&) // why not me? every time?
  {
    std::cout<<"EB Exception";
  }
  catch(EA&) // caught here??
  {
    std::cout<<"EA Exception";
  }

  std::cout<<" Finished"<<std::endl;

  return 0;
}

答案 1 :(得分:2)

正如[except.handle](工作草案)中的标准所述:

  

尝试块的处理程序按外观顺序进行尝试。这使得编写永远不会执行的处理程序成为可能,例如通过在相应基类的处理程序之后放置派生类的处理程序。

这正是你所做的。确实有趣。
反转处理程序以解决问题。

答案 2 :(得分:1)

因为catch块按照你声明的顺序检查。

你首先赶上EA&。 EB来自EA,所以这是一个有效的捕获,第二个捕获被忽略。

你想拥有最专业的&#34;异常捕获优先。因此,如果你切换catch块,它应该以另一种方式工作。

答案 3 :(得分:1)

按顺序检查

catch语句。 public static String view(String nameDoc){ String text = null; try{ XWPFDocument docx = new XWPFDocument( new FileInputStream(nameDoc)); XWPFWordExtractor we = new XWPFWordExtractor(docx); text = we.getText(); we.close(); docx.close(); }catch (Exception e){ e.printStackTrace(); } return text; } 匹配,因此使用它。永远无法匹配EA&。你需要先把更具体的问题放在首位。

EB&

答案 4 :(得分:1)

原因:

  

向上转型

派生类到基础。因此总是陷入第一次陷阱。