3

ここにあるmain()

int main()
{
    B b(1,"two","three");
    try
    {
        f1(b);
    }
    catch(B& b_ref)
    {
        cout<<"Caught B&"<<endl;
        b_ref.print();
    }
    catch(A& a_ref)
    {
        cout<<"Caught A&"<<endl;
        a_ref.print();
    }

    system("pause");
    return 0;
}

ここにあるf1()

void f1(A& subject)
{
    throw subject;
}    

情報:

B は A から継承します。A::print()仮想であり、B で再実装されます。例外をキャッチする catch は です。これはcatch(A& a_ref)、例外の静的な型 (サブジェクト) が A& であるため、理にかなっていると思います。しかし、なぜB:: print()実行されていないのですか?動的タイプは「失われた」ですか?ラインでのみA::print()実行されますa_ref.print();

誰か説明できますか?

4

5 に答える 5

6

throwそれに続く式の型のオブジェクトのみをスローします。この場合、は実際のオブジェクトが何であるかに関係なくsubject型であるため、がスローされます (参照はスローできないため、コピーが作成されることに注意してください)。A&A

例外をスローする例外クラスにメンバー関数を追加することで、これに対処できます。このメソッドをすべてのクラスに実装している限り、呼び出されるオーバーライドはオブジェクトのランタイム タイプを認識し、throw *this.

http://www.ddj.com/cpp/184401940

于 2009-08-03T10:55:39.263 に答える
6

C++ 標準 15.1/3 によると:

throw 式は、例外オブジェクトと呼ばれる一時オブジェクトを初期化します。その型は、throw のオペランドの静的型から最上位の cv 修飾子を削除することによって決定されます...

したがって、タイプ B ではなくタイプ A の一時オブジェクトを作成します。

于 2009-08-03T11:03:27.370 に答える
5

「 」と言うとthrow subject、スロー式の静的型に基づいて新しい例外オブジェクトが作成されます ( subject)。参照であるという事実subjectは、スローするオブジェクトを決定する目的には関係ありません。新しいAオブジェクトは、から構築されたコピーsubjectです。このコピー (またはこのコピーのコピー) が、実際にキャッチされるオブジェクトです。

于 2009-08-03T10:55:31.743 に答える
4

Catch ブロックはポリモーフィックに機能しますが、throw は機能しません。あなたが言う時:

void f1(A& subject)
{
    throw subject;
}

関数に渡されるものは B ですが、A をスローしています。

于 2009-08-03T11:00:15.600 に答える
-1

参照によってキャッチするため、オブジェクトは「スライス」されます。

本当にポリモーフィックな動作が必要な場合は、pimpl イディオムのようなものを使用してみてください。

于 2009-08-03T10:56:10.167 に答える