请考虑以下代码:
#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#。
答案 0 :(得分: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
答案 1 :(得分:0)
由于b
的构造失败,这会导致已经存在的c
被销毁,然后执行内部catch。
由于它重新抛出,外部try中已经存在的a
被破坏,外部catch被执行。
由于它再次重新播放,并且没有更多的捕获,异常超出了main()
,它由打印消息和中止的支持库处理。
销毁订单与建筑订单相反。因此,在c
之后构建的a
在之前被销毁。
b
和d
永远不会复活。
答案 2 :(得分:0)
#5
被破坏时,将显示 a
。这将在c
被销毁后发生,在e.what()
显示{{1}}后会发生{{1}}。