обработка нефатальных исключений c ++ - PullRequest
1 голос
/ 14 декабря 2010

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

return err("File could not be loaded");

, которые выводили бы ошибку на экран и возвращали false, завершая обработку инструкций.Было высказано предположение, что это будет лучше обрабатываться с исключениями.

Проблема в том, что программа, по сути, является языковым интерпретатором, управляемым через консоль, что означает, что в любое время вводится команданеправильно, или в интерпретируемом коде есть ошибка, должна отображаться ошибка.

Помимо того, что эти проблемы, по-видимому, незначительно обрабатываются как исключения, как это должно быть реализовано?Как блок try можно использовать для управления путями обработки?Например, в настоящее время мой код выглядит следующим образом:

if(!validate(code))
  return false; //the validate function already having output the error
else
  process(code);

Как мне обеспечить, чтобы процесс (код) выполнялся только в случае успешной проверки (кода)?Должен ли я просто return false; из функции в блоке catch?Казалось бы, это возвращает к первоначальной проблеме использования возвращаемых значений для обработки исключительных событий.Мне кажется, что основная проблема заключается в том, что эти проблемы вовсе не являются исключениями, но я полагаюсь на тех, у кого больше опыта, чем у меня.

Ответы [ 6 ]

4 голосов
/ 14 декабря 2010

Если операция может - по замыслу - либо завершиться успешно, либо завершиться неудачей, и оба они являются общими, может быть наиболее понятно структурировать поток команд таким образом, чтобы ошибки проверялись «явно», как в логическом значении « проверить "функцию.

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

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

3 голосов
/ 14 декабря 2010

Идея исключений заключается в том, что вам не понадобится что-то вроде отдельного шага проверки.Всякий раз, когда «процесс» попадает в точку, где что-то сломано, выдается исключение.

Если по какой-то причине вам нужен отдельный шаг проверки, он будет выглядеть как

validate(code);
process(code);

Validateвыдает исключение при сбое, и в этом случае процесс никогда не будет достигнут.

2 голосов
/ 14 декабря 2010

Возможно, вы хотите, чтобы ваш цикл верхнего уровня выглядел примерно так:

while (!quit) {
    try {
        process_command_line_input();
    }
    catch (const std::exception& ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
    }
}

Итак, process_command_line_input() получает следующую строку ввода и делает все, что делает.Если обнаружена какая-либо ошибка, возникает исключение, цикл верхнего уровня отображает его, а затем переходит к следующей строке ввода.

2 голосов
/ 14 декабря 2010
try
{
  validate(code);
  process(code);
} 
catch(...)
{
  return false;
}
return true;

Предполагая, что validate бросков, process не произойдет.

1 голос
/ 14 декабря 2010

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

Правильный способ сделать это, как

std::string code;
// input into code
try {
    validate(code);
    process(code); // Throws an exception.
}
catch(std::runtime_error& except) {
    std::cout << except.what();
    // recover from here.
}
0 голосов
/ 14 декабря 2010

Нет единого правильного ответа.
Это сильно зависит от кода и ситуации:

В вашей ситуации простой код, приведенный выше (если он принадлежит моему классу), тогда коды ошибокштраф:

class MyClass
{
    public:
        void processesValidCodesOrIgnore(int code)
        {
            if (validate(code))
            {
                processesCode(code);
            }
        }
    private:
        bool validate(int);
        void processesCode(int);
};

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

С другой стороныС другой стороны, если бы validate был общедоступным, я бы определенно рассмотрел возможность использования исключений (в зависимости от использования).Поскольку это заставило бы вызывающего абонента активно проверять проблемы, а не игнорировать их молча.

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