簡體   English   中英

來自std :: exception的C ++異常和繼承

[英]C++ Exceptions and Inheritance from std::exception

鑒於此示例代碼:

#include <iostream>
#include <stdexcept>

class my_exception_t : std::exception
{
public:
    explicit my_exception_t()
    { }

    virtual const char* what() const throw()
    { return "Hello, world!"; }
};

int main()
{
    try
        { throw my_exception_t(); }
    catch (const std::exception& error)
        { std::cerr << "Exception: " << error.what() << std::endl; }
    catch (...)
        { std::cerr << "Exception: unknown" << std::endl; }

    return 0;
}

我得到以下輸出:

Exception: unknown

然而,只是從std::exception public繼承my_exception_t ,我得到以下輸出:

Exception: Hello, world!

有人可以向我解釋為什么繼承類型在這種情況下很重要嗎? 獎勵積分作為標准中的參考。

當您私下繼承時,您無法轉換為或以其他方式訪問該類之外的基類。 既然你要求標准的東西:

§11.2/ 4:
如果可以訪問基類的發明公共成員,則可以訪問基類。 如果可以訪問基類,則可以隱式地將指向派生類的指針轉換為指向該基類的指針(4.10,4.11)。

簡單地說,對於類外的任何東西,它就像你從未繼承過std::exception ,因為它是私有的。 因此,它不能被std::exception&子句捕獲,因為不存在轉換。

有人可以向我解釋為什么繼承類型在這種情況下很重要嗎? 獎勵積分作為標准中的參考。

繼承的類型無關緊要。 只有您可以使用其中一種捕獲類型的可訪問轉換。 事實上,由於它不是公共繼承,因此沒有公共可訪問的轉換。


說明:

您可以在此處看到相同的行為:

class B
{
};

class C1 : B
{
};

class C2 : public B
{
};

int main(int argc, char** argv)
{
    B& b1 = C1();//Compiling error due to conversion exists but is inaccessible
    B& b2 = C2();//OK
    return 0;
}

如果出現以下情況,則拋出的異常僅由catch塊捕獲:

  1. catch塊具有匹配類型,或
  2. catch塊用於具有可訪問轉換的類型
  3. 捕獲塊是一個捕獲(...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM