Как я могу выполнить различные уловы в зависимости от того, с какой стороны я вышел за пределы? - PullRequest
0 голосов
/ 28 марта 2019

Я перегружен оператор, так что я могу вернуть значение массива.Я могу работать вне границ, используя 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 Ответ

4 голосов
/ 28 марта 2019

Можно ли генерировать исключение с другим 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 &)
{
    //...
}
catch (const OutOfBoundsInBack &)
{
    //...
}

В качестве альтернативы:

#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 &e)
{
    switch (e.whichSide)
    {
        case InFront:
            //...
            break;

        case InBack:
            //...
            break;
    }
}
...