3

あるインタビューで、値による例外のキャッチが問題になる理由を尋ねられたので、オブジェクトのスライスが発生する可能性があると答えました。そして、これは私がインターネットで見つけたものです。たとえば、ここにあります: https://www.viva64.com/en/w/v746/

しかし、今私は実験しようとしていますが、値でキャッチするときにスライスの例を見つけることができません。スライスの通常のシナリオ (例外はありません) は次のとおりです。

Derived d1;
Derived d2;
Base& b1 = d1;
Base& b2 = d2;
b1 = b2;

最後の行で Base の代入演算子が呼び出され、Derived オブジェクトの Base 部分のみがコピーされます。そのため、b1 のベース部分は d2 からコピーされますが、b1 の派生部分は d2 のままです。悪い。

しかし、例外を値でキャッチする場合、これはどのように発生するのでしょうか?

私はこのコードを試しました (g++ と Sun CC コンパイラの両方で):

struct Base
{
    virtual void print() const
    {
        cout << "{ Base: " << m << " }" << endl;
    }

    Base(int _m = 0) : m(_m) {}

    int m;
};

struct Derived : Base
{
    Derived(int _m = 0, int _n = 0) : Base(_m), n(_n) {}

    void print() const
    {
        cout << "{ Base: " << m << ", Derived: " << n << " }" << endl;
    }

    int n;
};

int main()
{
    try
    {
        try
        {
            throw Derived(3, 300);
        }
        catch(Base x)
        {
            cout << "Inner catch: ";
            x.print();
            throw;
        }
    }
    catch(Derived y)
    {
        cout << "Outer catch: ";
        y.print();
    }    
}

出力は次のとおりです。

Inner catch: { Base: 3 }
Outer catch: { Base: 3, Derived: 300 }

したがって、Derived 例外をスローし、その Base BY VALUE をキャッチして再スローし、次に Derived BY VALUE をキャッチすると、すべて正常に動作し、スライスはありません。それはどうですか?

また、誰かが BY VALUE をキャッチするときのスライスの例を提供できますか?

4

2 に答える 2