12

このサンプル コードを考えると:

#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

my_exception_tただし、 fromを継承するだけでstd::exception public、次の出力が得られます。

Exception: Hello, world!

この場合、継承のタイプが重要な理由を誰かに説明してもらえますか? 標準の参照のためのボーナス ポイント。

4

2 に答える 2

21

非公開で継承する場合、クラスの外部でその基本クラスに変換したり、アクセスしたりすることはできません。あなたが標準から何かを求めたので:

§11.2/4:
基本クラスの発明されたパブリック メンバーがアクセス可能である場合、基本クラスはアクセス可能であると言われます。基底クラスにアクセスできる場合、派生クラスへのポインターをその基底クラスへのポインターに暗黙的に変換できます (4.10、4.11)。

簡単に言えば、クラスの外部にあるものはstd::exception、プライベートであるため、 から継承したことがないようなものです。std::exception&したがって、変換が存在しないため、句にキャッチすることはできません。

于 2010-04-03T00:15:30.950 に答える
10

この場合、継承のタイプが重要な理由を誰かに説明してもらえますか? 標準の参照のためのボーナス ポイント。

継承の種類は問いません。catch 型の 1 つにアクセス可能な変換を使用できることだけが重要です。パブリック継承ではないため、パブリックにアクセス可能な変換はありません。


説明:

ここで同じ動作を確認できます。

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. catch ブロックは catch(...)
于 2010-04-03T00:13:07.697 に答える