Поймать и бросить операторы внутри функции - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть файл matrixType, который работает нормально, но сейчас я пытаюсь заменить операторы if на операторы try, catch и throw внутри функции класса.Я просто пытаюсь понять одну функцию, чтобы применить ее к другим.Поскольку я пытался выполнить операторы try и catch, но он пропустил оператор try и вызвал фактическое исключение, которое полностью останавливает программу.Одна из функций, на которой я фокусируюсь, это оператор равенства. Вот HeaderFile #pragma, как только #include #include #include #include #include #include

using namespace std;

class matrixType
{
private:
    int **matrix;
    int row;
    int col;
public:
    const matrixType& operator=(const matrixType& mat);
}

Вот файл class.cpp, который в настоящее время работает

#include "matrixType.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <stdexcept>
#include <limits>

using namespace std;

const matrixType& matrixType::operator=(const matrixType& mat)
{
    if (row != mat.row || col != mat.col)
    {
        cout << "The matrixes are not identical" << endl;
        return *this;
    }
    for (int i = 0; i < row; i++)
    {
        for (int r = 0; r < col; r++)
        {
            matrix[i][r] = mat.matrix[i][r];
        }
    }
    return *this;
}

Тогда это исходный файл

#include <iostream>
#include <string>
#include <stdexcept>
#include <limits>
#include "matrixType.h"
using namespace std;

int main()
{
    matrixType test1(3, 3);
    matrixType test2(2, 2);
    test1 = test2;

    return 0;
}

Таким образом, большой вопрос, как вы вызываете исключение, которое я пытался

Try
{
   if(mat.row != row || mat.col != col)
        throw exception("The matrixes are not identical")
}
catch (exception & e)
{
   cout << e.what << endl;
}

Что вызвало фактическое исключениевсплывающее окно, но когда я покидаю оператор if, он работает и не переходит в состояние сбоя.Кто-нибудь видит, что я делаю неправильно, если я заменил оператор if приведенным выше кодом?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Во-первых, заметка о значении исключений.Далее я расскажу о том, что не так с вашим кодом.

Значение выброса исключения в C ++ на английском языке примерно таково: «Я больше не могу справиться с этой ситуацией, я отказываюсьпрямо сейчас, и я надеюсь, что кто-то еще может справиться с этим ".Значение перехвата исключения примерно равно: «Ой, кто-то облажался, но я собираюсь что-то с этим сделать сейчас».Имея это в виду, давайте посмотрим, как это работает, более подробно.

Многие функции имеют предварительных условий , то есть те вещи, которые функция всегда ожидает, чтобы быть истинной, прежде чем она запустится.Например, функция squareRoot(double x) может иметь предварительное условие, что x никогда не должно быть отрицательным.Когда предварительное условие функции нарушается, для этой функции естественное время сказать: «Я сдаюсь сейчас, разберись с этим!»поскольку кто-то, кто вызвал эту функцию, делает что-то не так, и squareRoot не может это исправить.Это может выглядеть следующим образом:

// precondition: x must not be negative
double squareRoot(double x){
    if (x < 0.0){
        // precondition is violated
        throw std::runtime_error("input to squareRoot was negative");
        // the function exits here!
        // this point in code is not reachable
    }
    // otherwise, precondition is satisfied, it's safe to continue
    ...
    return result;
}

в другом месте, в дикой природе:

void myFunction(){
    double x;
    cout << "x = ";
    cin >> x;
    double y = squareRoot(x);
    cout << ", y = " << y << '\n';
}

Здесь, если кто-то вводит отрицательное число, то условия squareRoot нарушаютсяи это вызывает исключение.Это означает, что squareRoot не будет возвращать нормально , а также myFunction.Когда генерируется исключение, все прерывается до тех пор, пока вы не поймаете исключение, которое может произойти далеко за пределами текущей функции.

int main(){
    try {
        myFunction(); // this might throw

        // if myFunction() throws, the following output will not happen!
        cout << "Thanks! have a nice day.\n";
    } catch (std::runtime_error e) {
        // if myFunction() does throw, the error lands right here
        cout << "Oops! an error occurred: " << e.what() << '\n';
    }
    return 0;
}

Важно отметить, что исключения следует генерировать только тогда, когда действительно неправильно.Исключения составляют , а не замена обычной программной логики, и они не замена для проверки таких вещей, как пользовательский ввод.

О пользовательских классах:

Когда вы определяете пользовательский тип класса, если он имеет конструктор копирования, оператор копирования или деструктор, это, вероятно, означает, что ваш класс имеет конфиденциальную информацию, которая требует специальнойзаботиться о том, чтобы убирать и следить.Если вы написали хотя бы одну из этих функций, вам следует реализовать все три из них .В противном случае в вашу программу чрезвычайно легко внедрить утечки памяти, ложное совместное использование данных и все виды нежелательного неопределенного поведения.

Об операторе назначения копирования:

Назначение оператора назначения копирования, как в a = b;, состоит в том, чтобы после его запуска левый объект должен был логически совпадать с правый объект и правый объект не должны были измениться.Предыдущее состояние левого объекта в этот момент теряется.То, что в точности означает логически, означает вопрос о том, что представляет ваш класс.

В случае простой матрицы, я бы ожидал, что две матрицы будут идентичными, если они имеют одинаковую ширину, высоту и значения для всех элементов.и я бы соответственно реализовал оператор присваивания копии.Например:

Matrix& Matrix::operator=(const Matrix& other){
    releaseMemory(); // clean up old data
    resize(other.rows, other.cols); // allocate new data
    for (int i = 0; i < rows; ++i){
        for (int j = 0; j < cols; ++j){
            this->data[i][j] = other.data[i][j]; // copy each value
        }
    }
    return *this;
}

Я оставляю вам детали реализации.Вы должны быть в состоянии найти отличные примеры и подробные объяснения о том, как перегрузить операторы, написать свой собственный конструктор и деструктор копирования и о хорошей практике в целом, прочитав хорошую книгу по C ++ .

0 голосов
/ 28 февраля 2019

На самом деле я понял, что должен использовать операторы возврата, как это работает, когда я включил оператор возврата в функцию catch.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...