代码之家  ›  专栏  ›  技术社区  ›  MBZ

C++捕获catch(…)块中捕获的异常的描述

  •  23
  • MBZ  · 技术社区  · 15 年前

    我能得到被捕获的异常的描述吗

    catch(...)
    

    阻止?像这样的 std::异常。

    6 回复  |  直到 15 年前
        1
  •  44
  •   Steve Jessop    13 年前

    您可以使用一个技巧:

    catch(...) {
        handle_exception();
    }
    
    void handle_exception() {
        try {
            throw;
        } catch (const std::exception &e) {
            std::cout << e.what() << "\n";
        } catch (const int i) {
            std::cout << i << "\n";
        } catch (const long l) {
            std::cout << l << "\n";
        } catch (const char *p) {
            std::cout << p << "\n";
        } catch (...) {
            std::cout << "nope, sorry, I really have no clue what that is\n";
        }
    

    以此类推,对于你认为可能被抛出的不同类型。如果你真的对可能被扔的东西一无所知,那么即使是倒数第二个也是错误的,因为有人可能会扔一个 char* 它不指向以nul结尾的字符串。

    一般来说,扔掉任何不是垃圾的东西都是个坏主意 std::exception 或派生类。原因是什么 int 或字符串文本。我不认为我会把它作为正式界面的一部分。您抛出的任何异常都是正式接口的一部分,即使您忘记记录它们。

        2
  •  5
  •   Puppy    15 年前

    该块可能会捕获int、const char*或任何内容。编译器怎么可能知道如何描述一个一无所知的东西呢?如果要从异常中获取信息,必须知道类型。

        3
  •  4
  •   jdisk    15 年前

    catch(std::exception& e) {...e.what()... }
    

    否则,正如DeadMG所写的,既然你可以扔(几乎)所有的东西,你就不能假设你抓到了什么。

    通常情况下,catch(…)只能在使用写得不好或有文档记录的外部库时用作最后的防御措施。所以你会使用层次结构

    catch(my::specialException& e) {
          // I know what happened and can handle it
          ... handle special case
          }
    catch(my::otherSpecialException& e) {
          // I know what happened and can handle it
          ... handle other special case
          }
    catch(std::exception& e) {
          //I can at least do something with it
          logger.out(e.what());
          }
    catch(...) {
         // something happened that should not have 
         logger.out("oops");
         }
    
        4
  •  3
  •   M.M    11 年前

    由于C++ 11,您可以用指针捕获当前异常:

    std::exception_ptr p;     // default initialization is to nullptr
    
    try {
          throw 7;
    }
    catch(...)
    {
         p = std::current_exception();
    }
    

    稍后(甚至可能在不同的函数中)您可以按照与当前最重要答案类似的方式执行操作:

    try {
        if ( p )
            std::rethrow_exception(p);
    }
    catch(int x)
    {
    
    }
    catch(std::exception &y)
    {
    }
    
        5
  •  2
  •   liaK    15 年前

    我们实现异常的方式是,我们有自己的异常类,它们都是从 std::exception ..

    我们的例外将包含 异常消息、函数名、文件名和行 生成异常的位置。这些都很有用,不仅可以显示消息,还可以用于 这有助于非常容易地诊断异常。所以,我们得到了生成的异常的全部信息。

    我们

        6
  •  2
  •   Community Mohan Dere    9 年前

    bobah

    #include <iostream>
    
    #include <exception>
    #include <typeinfo>
    #include <stdexcept>
    
    int main()
    {
        try {
            throw ...; // throw something
        }
        catch(...)
        {
            std::exception_ptr p = std::current_exception();
            std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
        }
        return 1;
    }