Я только что исправил очень тонкий баг в нашем коде, вызванный разрезанием исключения, и теперь я хочу убедиться, что я точно понимаю, что происходит.Исключение среза - это из-за сгенерированного конструктора копирования?
Вот наш базовый класс исключений, производный класс, и соответствующие функции:
class Exception
{
public:
// construction
Exception(int code, const char* format="", ...);
virtual ~Exception(void);
<snip - get/set routines and print function>
protected:
private:
int mCode; // thrower sets this
char mMessage[Exception::MessageLen]; // thrower says this FIXME: use String
};
class Derived : public Exception {
public:
Derived (const char* throwerSays) : Exception(1, throwerSays) {};
};
void innercall {
<do stuff>
throw Derived("Bad things happened!");
}
void outercall {
try {
innercall();
}
catch(Exception& e)
{
printf("Exception seen here! %s %d\n", __FILE__, __LINE__);
throw e;
}
}
ошибка была, конечно, что outercall заканчивает бросать исключение, а не производный. Моя ошибка возникла из-за того, что в стеке вызовов было больше попыток поймать Derived failing.
Теперь я просто хочу убедиться, что я понимаю - я считаю, что на линии «throw e» создается новый объект Exception с использованием конструктора копии по умолчанию. Это то, что на самом деле происходит?
Если это так, мне разрешено блокировать конструкторы копирования для объектов, которые будут выбрасываться? Я бы предпочел, чтобы это не повторилось, и наш код не имеет причины копировать объекты Exception (что я знаю).
Пожалуйста, никаких комментариев о том, что у нас есть своя собственная иерархия исключений. Это немного старый дизайн, над которым я работаю, чтобы исправить (я добиваюсь хорошего прогресса. Я избавился от домашнего класса струн и многих отечественных контейнеров.)
ОБНОВЛЕНИЕ: Чтобы быть ясным, я исправил ошибку (изменив «throw e» на «throw»), прежде чем задавать вопрос. Я просто искал подтверждения того, что происходит.
Я знаю, что вы сказали, что не беспокоитесь о других вещах, но просто еще две вещи: сделайте свой класс 'Exception' унаследованным от' std :: exception' и поймайте вещи 'const &'. – GManNickG
В чем преимущество ловить как const? Я всегда поймаю по ссылке, но почему const? (не то, что я могу сделать это с этим классом в любой момент, но в один прекрасный день ...) –
@ Kohne: Преимущество const в этой настройке аналогично тому, как в любой другой настройке - вы четко указываете намерение, t намерены изменить состояние объекта и что компилятор должен убедиться, что вы этого не сделаете - идея const заключается в том, что неизменные объекты легче рассуждать (т.е. отлаживать, тестировать, доказывать корректность кода), поскольку они помогают в письменной форме ссылаться прозрачный код –