3

考虑下面的代码:

#include <iostream>
#include <stdexcept>

class E{
    public:
        E(int n):m_n(n)
    {
        if (0>n)
        {
            throw std::logic_error("5");
        }
    }
        ~E(){cout << m_n << "#" <<endl;}
    public :
        int m_n;
};

int main()
{
    try{
        E a(5);
        try{
            E c(7);
            E b(-8);
            E d(9);
        }
        catch(const std::exception &e)
        {
            cout <<2 <<"&&&"<<e.what()<<endl;
            throw e;
        }
    }
    catch(const std::exception &e)
    {
        cout <<3 << "^^^^^ "<<e.what() << endl;
        throw e;
    }
    return 0;
} 

我得到的输出是:

7#
2&&&5
5#
3^^^^^ St9exception
std::exception: St9exception
Aborted.

有人可以解释为什么这样的输出吗?我希望显示第一个 5#。

4

3 回答 3

5

这是您的程序在伪代码中的工作流程:

{
  //outer try
  create e(5);
  {
    //inner try
    create e(7);
    failed create e(-8);//exception here
    throw;
    delete e(7);//-> 7#
  }
  {
    //catch in inner try;
    cout &&&;//-> 2&&&5
    throw e; // throw sliced copy of original exception
  }
  delete e(5);//-> 5#
}
{
  //catch in outer try
  cout ^^^^;//-> 3^^^^^ St9exception (the last thrown is pure std::exception)
  throw e; // throw another copy, no more slicing as it's already exception
}
program termination because of uncaught exception;
//-> std::exception: St9exception
//-> Aborted.

//return 0; was never reached
于 2013-06-27T10:53:58.823 回答
0

由于构造b失败,这导致已经存在c的被破坏,然后执行内部catch。

既然是重新抛出,那么a外层try中已经存在的就被销毁,外层catch被执行。

由于它再次重新抛出,并且没有更多的捕获,异常退出main(),由打印消息并中止的支持库处理。

破坏顺序与构造顺序相反。所以c,that 是在 之后构造a的,在 之前是被销毁的。

b, 和d, 从未出现过。

于 2013-06-27T11:02:55.580 回答
0

#5a被破坏时会显示。这将在c被破坏后发生,这发生在您显示后的堆栈展开e.what()中。

于 2013-06-27T11:44:46.447 回答