简体   繁体   English

C ++获取了catch(...)块中捕获的异常的描述

[英]C++ get description of an exception caught in catch(…) block

can I get description of an exception caught by 我可以获得被捕获的异常的描述吗?

catch(...)

block? 块? something like .what() of std::exception. 像std :: exception的.what()之类的东西。

There is one trick you might be able to use: 您可以使用一个技巧:

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";
    }

and so on, for as many different types as you think might be thrown. 等等,你可能会抛出许多不同的类型。 If you really know nothing about what might be thrown then even that second-to-last one is wrong, because somebody might throw a char* that doesn't point to a nul-terminated string. 如果你真的不知道什么可能被抛出,那么即使是倒数第二个也是错误的,因为有人可能会抛出一个不指向以空字符结尾的字符串的char*

It's generally a bad idea to throw anything that isn't a std::exception or derived class. 抛出任何不是std::exception或派生类的东西通常是个坏主意。 The reason std::exception exists is to allow everybody to throw and catch objects that they can do something useful with. std::exception存在的原因是允许每个人抛出并捕获他们可以做一些有用的对象。 In a toy program where you just want to get out of there and can't even be bothered to include a standard header, OK, maybe throw an int or a string literal. 在玩具程序中,你只想离开那里,甚至不能打扰包含一个标准的标题,好吧,可能会抛出一个int或一个字符串文字。 I don't think I'd make that part of a formal interface. 我不认为我会成为正式界面的一部分。 Any exceptions you throw are part of your formal interface, even if you somehow forgot to document them. 您抛出的任何异常都是正式界面的一部分,即使您以某种方式忘记记录它们。

That block might catch an int, or a const char*, or anything. 该块可能捕获一个int,或一个const char *,或任何东西。 How can the compiler possibly know how to describe something when it knows nothing about it? 当编译器对它一无所知时,编译器怎么可能知道如何描述呢? If you want to get information off an exception, you must know the type. 如果要从异常中获取信息,则必须知道类型。

If you know you only throw std::exception or subclasses, try 如果您知道只抛出std :: exception或子类,请尝试

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

Otherwise, as DeadMG wrote, since you can throw (almost) everything, you cannot assume anything about what you caught. 否则,正如DeadMG写的那样,既然你可以扔掉(差不多)所有东西,你就不能假设你抓到了什么。

Normally catch(...) should only be used as the last defense when using badly written or documented external libraries. 通常,catch(...)应仅用作使用写得不好或记录在案的外部库的最后防御。 So you would use an hierarchy 所以你会使用层次结构

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");
     }

Since C++11 you can capture the current exception with a pointer: 从C ++ 11开始,您可以使用指针捕获当前异常:

std::exception_ptr p;     // default initialization is to nullptr

try {
      throw 7;
}
catch(...)
{
     p = std::current_exception();
}

This behaves like a smart pointer; 这表现得像一个智能指针; so long as there is at least one pointer pointing to the exception object it is not destroyed. 只要至少有一个指针指向异常对象,它就不会被销毁。

Later (maybe even in a different function) you can take action in a similar way to the current top answer: 稍后(甚至可能在不同的功能中)您可以采用与当前最佳答案类似的方式采取措施:

try {
    if ( p )
        std::rethrow_exception(p);
}
catch(int x)
{

}
catch(std::exception &y)
{
}

Quoting bobah 引用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;
}

How we have our exceptions implemented is that, we have our own Exception classes, that are all derived from std::exception .. 我们如何实现我们的异常是,我们有自己的异常类,它们都是从std::exception派生的。

Our exceptions will contain Exception message, Function name, File name and line where exceptions are generated. 我们的例外将包含异常消息,函数名称,文件名和生成异常的 These are all useful not just to show the Messages but also can be used for logging which helps to diagnose the Exception quite easily. 这些都不仅可用于显示消息,还可用于记录 ,这有助于非常容易地诊断异常。 So, we get the entire information about the Exceptions generated. 因此,我们获得有关生成的异常的完整信息。

Remember exceptions are for us to get information about what went wrong. 请记住,例外情况是我们可以获取有关出错的信息。 So, every bit of information helps in this regard.. 所以,在这方面,每一点信息都有帮助..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM