繁体   English   中英

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

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

我可以获得被捕获的异常的描述吗?

catch(...)

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

您可以使用一个技巧:

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*

抛出任何不是std::exception或派生类的东西通常是个坏主意。 std::exception存在的原因是允许每个人抛出并捕获他们可以做一些有用的对象。 在玩具程序中,你只想离开那里,甚至不能打扰包含一个标准的标题,好吧,可能会抛出一个int或一个字符串文字。 我不认为我会成为正式界面的一部分。 您抛出的任何异常都是正式界面的一部分,即使您以某种方式忘记记录它们。

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

如果您知道只抛出std :: exception或子类,请尝试

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

从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)
{
}

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

我们如何实现我们的异常是,我们有自己的异常类,它们都是从std::exception派生的。

我们的例外将包含异常消息,函数名称,文件名和生成异常的 这些都不仅可用于显示消息,还可用于记录 ,这有助于非常容易地诊断异常。 因此,我们获得有关生成的异常的完整信息。

请记住,例外情况是我们可以获取有关出错的信息。 所以,在这方面,每一点信息都有帮助..

暂无
暂无

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

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