В одном из интервью меня спросили, почему перехват исключений по значению может быть проблемой, и я ответил, что это может вызвать нарезку объектов.И вот что я нахожу в Интернете, например, здесь: https://www.viva64.com/en/w/v746/
Но сейчас я пытаюсь экспериментировать и не могу найти пример нарезки при ловле по значению.Обычный сценарий нарезки (без исключений) таков:
Derived d1;
Derived d2;
Base& b1 = d1;
Base& b2 = d2;
b1 = b2;
В последней строке вызывается оператор присваивания 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 и все работает нормально, без нарезки.Как это?
А кто-нибудь может привести пример нарезки при ловле по значению?