что нельзя сделать с помощью условия else и можно сделать с обработкой исключений? - PullRequest
4 голосов
/ 08 июня 2011

что нельзя сделать с помощью условия else и можно сделать с обработкой исключений?

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

Является ли обработка исключений просто прославленным способом отображения ошибок?

Ответы [ 7 ]

3 голосов
/ 08 июня 2011

В самых ранних реализациях C ++ исключения были скомпилированы в эквивалентные конструкции if / else, более или менее.И они были медленными, как патока, до такой степени, что вы все еще можете найти руководства по программированию, которые рекомендуют против исключений на том основании, что «они медленные».

Так что это не вопрос «может» или «не может»».Это вопрос читабельности и производительности.

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

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

2 голосов
/ 08 июня 2011

Послушайте, вы ничего не можете сделать с исключениями, которые вы не можете сделать с ассемблером 8086, написанным вручную. (Тьюринг завершен!) За исключением того, что ассемблер с ручным кодированием не очень хороший инструмент для проекта со строками кода в 100 000 штук, если только вы не лучший программист в Млечном Пути, если тогда. Опыт показывает, что в ряде случаев обработка исключений дает наиболее надежный код, написанный обычными людьми. Пример ctors в Sharptooth хорош. Как и ошибки, которые должны распространяться вверх по стеку вызовов. Редактировать: А сколько людей на самом деле проверяют, что malloc не терпел неудачу каждый раз? Лучше бросить OutOfMemoryException.

2 голосов
/ 08 июня 2011

Некоторые языки (например, C ++) не позволяют возвращать значения в некоторых случаях. Например, в конструкторах C ++ нет возвращаемых значений (даже void), поэтому единственный способ сообщить об ошибке в конструкторе - вызвать исключение.

1 голос
/ 08 июня 2011

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

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

Конкретно, используйте следующую фиктивную функцию для работы с текстом в редакторе:

do-stuff:
    backward-line 10
    x = point
    search-for "FOO"
    return buffer-substring x point

И "back-line", и "search-for" могут не работать. Если бы мне пришлось самостоятельно обрабатывать ошибки, я должен был бы их проверять. Кроме того, мне пришлось бы изобрести побочный канал, чтобы сообщить своему абоненту, что произошла ошибка. Как я уже сказал, это можно сделать, но это было бы намного сложнее.

1 голос
/ 08 июня 2011

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

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

  • Файл не найден.
  • Файл существует, но не может быть прочитан.
  • Файл был удален в серединеоперация чтения.

Вы могли бы обрабатывать все это с помощью блоков if-else, но с исключениями это сделать намного проще.

0 голосов
/ 08 июня 2011

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

Пример: a() вызывает b() иb() звонки c()c() может возникнуть ошибка, которая должна быть обработана в a().Без обработки исключений вам придется иметь дело с этим, используя возвращаемые значения Sentinel в b() и c() и дополнительный проверочный код в b().Вы можете представить, сколько еще кода вам нужно написать, если ошибка должна пройти через большее количество уровней, от того, что вызвало ее, до того, что должно ее обработать.

Это краткая версия моего ответа на другой вопрос , который был задан здесь ранее и перенесен.

0 голосов
/ 08 июня 2011

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

void complexFunction()
{
   //do stuff, then
   if( timeToBailOut() ) {
      // what? how would you get out of all instances at once?
   }       
}

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

if( timeToBailOut() ) {
    throw BailOutException();
}
...