簡體   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