2010-12-13 3 views
1

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

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

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

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

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

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

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

+0

Вы, несомненно, получите много ответов по строкам «исключения для исключительных ситуаций». Пожалуйста, проигнорируйте их. –

+0

@John Dibling: Исключения или комментарии? –

+0

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

ответ

2
try 
{ 
    validate(code); 
    process(code); 
} 
catch(...) 
{ 
    return false; 
} 
return true; 

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

1

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

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

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

1) Это только правильный способ при очень небольшом наборе предполагаемых обстоятельств. 2) Используйте cerr для сообщения об ошибках! –

3

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

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

validate(code); 
process(code); 

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

+0

Но не означает ли это, что код полностью завершится в случае исключения? Если нет, как код вернется в основной контур консоли? Edit: Я понимаю, что вы говорите. Не поймал предполагаемый блок try. – wyatt

+1

'while (! Quit) {try {process_command_line(); } catch (const std :: exception & ex) {cout << "Ошибка:" << ex.what() << endl; }} ' –

+0

+1 для первого абзаца. Код проверки легко настроить с помощью кодов возврата, в то время как код обработки может быть легко на несколько слоев, где коды возврата будут неудобны. –

4

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

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

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

2

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

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

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

0

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

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

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

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

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

Смежные вопросы