#c #exception #try-catch
#c #исключение #попробуйте-перехват
Вопрос:
Я перегрузил оператор таким образом, что могу возвращать значение массива. Я могу обрабатывать выход за пределы с помощью if
:
float arr::operator[](const int i) const
{
if (i < 0)
{
cout << "Outside of array, first entry returned" << endl;
return value[0];
}
else if (i >=size)
{
cout << "Outside of array, last entry returned" << endl;
return value[size-1];
}
else return value[i];
}
но я изучаю исключения и блоки try-catch.
Возможно ли создать исключение с другим значением int (например) для выхода за верхние / нижние границы и иметь перехваты, которые выполняют другой код в зависимости от значения этого int?
Я знаю, что здесь это if
хорошо работает, но я хочу развить свои знания для использования в более сложных идеях.
Комментарии:
1. Не используйте целые числа. Выбросить тип .
2. Ах да, я рассматривал это, но это кажется неуклюжим? Выбросить значение int для нижележащих границ и строку для вышележащих? Это лучшее решение?
3. Совсем не неуклюжий и мгновенно узнаваемый для любого, кто читает ваш код. Назовите тип правильно, и код почти самодокументируется. У программиста, который видит
throw 42;
, скорее всего, возникнет момент WTF, за которым последует поиск по коду, пытаясь выяснить, что вы делаете, или тот же момент WTF, за которым последует выбрасывание вашего кода в мусорное ведро. Но если они видятthrow lowerbound;
, это им о чем-то говорит.4. Почему вы не выполняете выборку напрямую
std::out_of_range
?5. @raindrop7 Насколько я мог видеть, он не различал low и high, просто это было вне границ.
Ответ №1:
Возможно ли создать исключение с другим значением int (например) для выхода за верхние / нижние границы и иметь перехваты, которые выполняют другой код в зависимости от значения этого int?
Вроде того. Вы, конечно, можете выдать другое int
значение на основе условия, но вам пришлось бы перехватывать одно общее int
и проверять его значение, вы не можете перехватывать разные int
значения по отдельности. Например:
const int OutOfBoundsInFront = -1;
const int OutOfBoundsInBack = 1;
float arr::operator[](const int i) const
{
if (i < 0)
throw OutOfBoundsInFront;
if (i >= size)
throw OutOfBoundsInBack;
return value[i];
}
...
try
{
... = myarr[index];
}
catch (int value)
{
switch (value)
{
case OutOfBoundsInFront:
//...
break;
case OutOfBoundsInBack:
//...
break;
}
}
Однако при создании исключения лучше создавать объект вместо простого типа POD. catch
блоки имеют дело с типами, а не со значениями. В этом случае вы можете определить разные типы классов для каждого условия, которое вы хотите перехватить. Например:
#include <stdexcept>
class OutOfBoundsInFront : public std::out_of_range
{
public:
OutOfBoundsInFront() : std::out_of_range("out of bounds in front") {}
};
class OutOfBoundsInBack : public std::out_of_range
{
public:
OutOfBoundsInBack() : std::out_of_range("out of bounds in back") {}
};
float arr::operator[](const int i) const
{
if (i < 0)
throw OutOfBoundsInFront();
if (i >= size)
throw OutOfBoundsInBack();
return value[i];
}
...
try
{
... = myarr[index];
}
catch (const OutOfBoundsInFront amp;)
{
//...
}
catch (const OutOfBoundsInBack amp;)
{
//...
}
Альтернативно:
#include <stdexcept>
class OutOfBoundsOnSide : public std::out_of_range
{
public:
enum WhichSide { InFront, InBack };
static const char* WhichSideErrorMsg[] = {
"out of bounds in front",
"out of bounds in back"
};
WhichSide whichSide;
OutOfBoundsOnSide(WhichSide side) : std::out_of_range(WhichSideErrorMsg[side]), whichSide(side) {}
};
class OutOfBoundsInFront : public OutOfBoundsOnSide
{
public
OutOfBoundsInFront() : OutOfBoundsOnSide(InFront) {}
};
class OutOfBoundsInBack : public OutOfBoundsOnSide
{
public
OutOfBoundsInBack() : OutOfBoundsOnSide(InBack) {}
};
float arr::operator[](const int i) const
{
if (i < 0)
throw OutOfBoundsInFront();
if (i >= size)
throw OutOfBoundsInBack();
return value[i];
}
...
try
{
... = myarr[index];
}
catch (const OutOfBoundsOnSide amp;e)
{
switch (e.whichSide)
{
case InFront:
//...
break;
case InBack:
//...
break;
}
}
Комментарии:
1. Эй, кажется, это отличный ответ! Несколько решений усложняются. Я только что многому научился! (Кроме того, ты всегда был моим любимым из Людей Икс 😉 )