【问题标题】:C++ -- Why 'what' print "Unknown exception" in catch scope?C++——为什么在捕获范围内打印“未知异常”?
【发布时间】:2011-10-24 11:37:34
【问题描述】:
try
{
    range_error r("Hi I am hereeeee!");
    cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
    exception *p2 = &r; 
    cout << p2->what() << endl; // print "Hi I am hereeeee!"  // case two
    throw p2;
}
catch (exception *e)
{
    cout << e->what() << endl;  // print "Unknown exception"  // case three
}

问题>

我不知道为什么案例 3 打印“未知异常”而不是“嗨,我是 hereeeee!”? 打印结果是从VS2010复制过来的

【问题讨论】:

  • 为什么这会导致投票失败?我投票赞成。

标签: c++


【解决方案1】:

因为当您到达catch 时,您的range_error 已被销毁,并且您正在捕捉一个悬空指针。将 range_error 声明移到 try 块之外,或者更好的是,抛出一个实例并通过引用捕获。

【讨论】:

    【解决方案2】:

    此程序会导致未定义的行为。因为变量r 是在try 块内声明的内部,所以在调用catch 处理程序之前它超出了范围。此时,e 指向堆栈上的某个区域,其中存在 range_error 类型的对象曾经存在。

    以下程序应打印预期结果:

    range_error r("Hi I am hereeeee!");
    try
    {
        cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
        exception *p2 = &r; 
        cout << p2->what() << endl; // print "Hi I am hereeeee!"  // case two
        throw p2;
    }
    catch (exception *e)
    {
        cout << e->what() << endl;  // print "Hi I am hereeeee!"  // case three
    }
    

    但是,您不应该抛出指向对象的指针,而应该抛出对象本身。运行时库将存储range_error 对象的副本并将该副本传递给异常处理程序。

    因此,您应该改用以下代码:

    try
    {
        range_error r("Hi I am hereeeee!");
        cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
        throw r;
    }
    catch (const exception& e)
    {
        cout << e.what() << endl;  // print "Hi I am hereeeee!"  // case two
    }
    

    【讨论】:

    • 我应该自己发现了这个问题。谢谢
    • 天哪,你一定抄袭了我,除非你的回答更好。
    • @John:除此之外,我也先发帖,并修复了catch块中的评论;-)
    • 除了按值抛外,一般采用的做法是catch by reference。答案中的代码已经是这样了,但我认为它值得明确说明。
    • @ncases:确实。但是,OP 一直在询问有关异常处理的几个问题,并且似乎很清楚异常处理程序中的 slicing 对象。
    【解决方案3】:

    因为在您捕获异常时,指向的异常对象已经超出范围。如果你写了

    range_error r("Hi I am hereeeee!");
    try
    {
        cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
        exception *p2 = &r; 
        cout << p2->what() << endl; // print "Hi I am hereeeee!"  // case two
        throw p2;
    }
    catch (exception *e)
    {
        cout << e->what() << endl;  // print "Unknown exception"  // case three
    }
    

    它会打印出你所期望的。

    【讨论】:

      猜你喜欢
      • 2011-03-05
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      • 1970-01-01
      相关资源
      最近更新 更多