Конструкция try - catch. Как правильно использовать при проверке входных данных?

Всем привет, я пишу свой класс, который предназначен для действий над матрицами. В нём присутствуют методы, в которых необходимо проверять входные данные. Я написал метод insert, который вставляет строку или столбец со значениями value в исходную матрицу на позицию index (что-то типо такого же метода из библиотеки NumPy в python). Для проверки этого индекса и оси реализовал try-catch. Всё работает за исключением случая, когда index больше на единицу, чем размер по выбранной оси исходной матрицы. При таких входных данных срабатывает try-catch, однако код выполняется дальше и строка с переданным значением вставляется в самый конец матрицы. Я думал, что данную проблему можно решить, запихнув весь код метода в try-catch или разместив функцию, которая прерывает код программы, в блок catch. Сам вопрос заключается в следующем: на сколько целесообразно и этично делать так, как я хотел. И вообще нужен ли блок try-catch в таких случаях, ведь можно организовать проверку входных данных с помощью if-else и, если проверка не будет пройдена, вывести сообщение на экран и вызвать функцию, прерывающую программу. Ниже привёл часть кода класса, который необходим для работы метода и .cpp файл, в котором вызывается метод с проблемными входными данными.

matrix.h

#include <iostream>
#include <cstdlib>

using std::cout;
using std::endl;
using std::cin;

template <typename T>
class Matrix
{
public:
Matrix()
{
    lines = columns = size = 0;
    arr = nullptr;
    shape = nullptr;
}



Matrix(const int lines, const int columns)
{
    this->lines = lines;
    this->columns = columns;
    size = lines * columns;
    shape = new int[2] {lines, columns};
    arr = new T * [lines];

    for (int i = 0; i < lines; i++) {
        arr[i] = new T[columns];
    }
}



Matrix(const Matrix& other)
{
    this->lines = other.lines;
    this->columns = other.columns;
    this->size = other.size;
    this->shape = new int[2] {other.lines, other.columns};
    this->arr = new T * [other.lines];

    for (int i = 0; i < other.lines; i++) {
        this->arr[i] = new T[other.columns];
    }

    for (int i = 0; i < other.lines; i++) {
        for (int j = 0; j < other.columns; j++) {
            this->arr[i][j] = other.arr[i][j];
        }
    }

}



    ~Matrix()
{
    clearMemory(arr, lines);
    delete[] shape;
}



void fillAuto(const int a, const int b)
{
    for (int i = 0; i < lines; i++) {
        for (int j = 0; j < columns; j++) {
            arr[i][j] = rand() % (b - a + 1) + a;
        }
    }
}



void printMatrix(char* name = nullptr)
{
    if (name != nullptr) {
        cout << name << endl;
    }

    for (int i = 0; i < lines; i++) {
        cout << '|' << ' ';

        for (int j = 0; j < columns; j++) {
            if (j == columns - 1) {
                if (arr[i][j] > -1) {
                    cout << ' ' << arr[i][j] << ' ';
                }
                else {
                    cout << arr[i][j] << ' ';
                }
            }
            else {
                if (arr[i][j] > -1) {
                    cout << ' ' << arr[i][j] << '\t';
                }
                else {
                    cout << arr[i][j] << '\t';
                }
            }
        }

        cout << ' ' << '|' << endl;
    }

    cout << endl;
}



Matrix insert(const int index, const int value, const int axis)
{
    // Чтобы проверить принадлежность index допустимому диапозону,
    // необходимо знать какая ось была передана.

    try
    {
        bool isIndexRande;

        if (0 == axis) {
            isIndexRande = (index > -1) && (index < this->lines);
        }
        else if (1 == axis) {
            isIndexRande = (index > -1) && (index < this->columns);
        }
        else {
            throw std::exception("Ошибка! Переданная ось вне "
                "допустимого диапозона!");
        }

        if (!isIndexRande) {
            throw std::exception("Ошибка! Переданный индекс вне "
                "допустимого диапозона!");
        }
    }
    catch (const std::exception& ex)
    {
        cout << ex.what() << endl;
    }

    Matrix temp;

    if (0 == axis) {
        temp.lines = this->lines + 1;
        temp.columns = this->columns;
        temp.size = (this->lines + 1) * this->columns;
        temp.shape = new int[2] {this->lines + 1, this->columns};
        temp.arr = new T * [this->lines + 1];

        for (int i = 0; i < this->lines + 1; i++) {
            temp.arr[i] = new T[this->columns];
        }

        // Вспомогательная переменная.
        // Пока цикл (i) не дошёл до переданного индекса (строки),
        // каждый элемент исходной матрицы копируется в ту же позицию
        // новой матрицы. Поэтому изначально a = 0.
        int a = 0;

        for (int i = 0; i < this->lines + 1; i++) {
            for (int j = 0; j < this->columns; j++) {

                if (i == index) {
                    temp.arr[i][j] = value;

                    // Т.к. цикл дошёл до переданной строки (index),
                    // в iую строку вставлялось новое значение на
                    // протяжении всей итерации. Если после этого
                    // использовать те же индексы, то будет пропущена
                    // строка в исходной матрицы. Поэтому, начиная
                    // со следующей строки после index, необходимо
                    // обращаться к исходной матрицы на одну строку ниже.
                    a = 1;
                }
                else {
                    temp.arr[i][j] = this->arr[i - a][j];
                }
            }
        }
    }
    else if (1 == axis) {
        temp.lines = this->lines;
        temp.columns = this->columns + 1;
        temp.size = this->lines * (this->columns + 1);
        temp.shape = new int[2] {this->lines, this->columns + 1};
        temp.arr = new T * [this->lines];

        for (int i = 0; i < this->lines; i++) {
            temp.arr[i] = new T[this->columns + 1];
        }

        for (int i = 0; i < this->lines; i++) {

            int a = 0;

            for (int j = 0; j < this->columns + 1; j++) {

                if (j == index) {
                    temp.arr[i][j] = value;
                    a = 1;
                }
                else {
                    temp.arr[i][j] = this->arr[i][j - a];
                }
            }
        }
    }

    return temp;
}



private:
T** arr;
int lines;
int columns
int size;
const int* shape;



template <typename T1>
void clearMemory(T1** mas, int n, bool isSquare=true)
{
    if (isSquare) {
        for (int i = 0; i < n; i++) {
            delete[] mas[i];
        }

        delete[] mas;
    }
    else {
        delete[] mas;
    }

}
};

matrix.cpp

#include <iostream>

int main()
{
using std::cout;
using std::endl;

setlocale(LC_ALL, "rus");

Matrix<int> a(3, 3);
a.fillAuto(-10, 10);
a.printMatrix();

Matrix<int> c = a.insert(3, 1000, 0);
c.printMatrix();

return 0;
}

Ответы (0 шт):