С++ Обработка ошибок - хорошие источники кода примера?

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

Где можно найти хорошие примеры кода обработки ошибок С++? Конкретные книги, конкретные проекты с открытым исходным кодом (предпочтительно с файлами и функциями для просмотра), а также конкретные веб-страницы или сайты будут с благодарностью приняты.

Ответ 1

Книга Herb Sutter и Andrei Alexandrescu Стандарты кодирования С++ содержит целую главу об обработке ошибок и исключениях, включая

  • Обеспечьте свободу документировать внутренние предположения и инварианты
  • Установите правильную политику обработки ошибок и строго следуйте за ней.
  • Различать ошибки и ошибки
  • Дизайн и запись кода с ошибкой
  • Предпочитают использовать исключения для сообщения об ошибках
  • Бросить по значению, уловить по ссылке
  • Сообщить, обрабатывать и переводить ошибки соответствующим образом
  • Избегайте спецификаций исключений

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

Ответ 2

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

Использовать коды ошибок для потока программы. Если у вас есть ожидаемая ошибка, не бросайте исключение. Например. вы читаете файл, вы можете выдать исключение для "file not found", "file locked"; но никогда не бросайте его для "конца файла".

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

Во-вторых, будьте очень осторожны с иерархиями исключений. Вы можете подумать, что он имеет класс Exception, а затем выводит из него NetException, а затем SMTPException для вашего SMTP-класса. Но если вы не держите общие данные в базовом классе, вам всегда придется поймать все типы исключений в этой иерархии. Например. если вы поместите причину ошибки SMTP в свой класс SMTPException, вы должны поймать его - если вы только поймаете типы Exception, у вас не будет доступа к членам SMTPException. Хорошим обходным решением этой проблемы является наличие в базовом классе исключения строки и int-члена и использование их только для производных типов. К сожалению, std::exception предлагает только строку: (

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

Если вы используете исключения, вы должны взять на себя задачу заполнить их большим количеством данных, чем с кодом ошибки. С ошибками вы должны обращаться с ними немедленно или они теряются в коде. За исключением этого, он может оказаться пойманным на многих уровнях от того места, где он был выброшен - например, в примере Родди. DoC вызывается и получает исключение 2 уровня из DoA. Если вы не укажете, что ошибка будет специфичной для кода в DoA, вы можете подумать, что она была выбрана из функции DoB. (простой пример, но я видел код, в котором исключение обрабатывалось на многих уровнях в стеке вызовов. Это было bstrd для отладки. Это особенно относится к программам OO)

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

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

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

Ответ 3

Я предпочитаю обработку исключений, обсуждаемую в этой статье. Это приводит к чистому коду и позволяет избежать явного создания/удаления объектов только для обработки исключений. http://www.informit.com/articles/article.aspx?p=373339

Ответ 4

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

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

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

В C типичный сценарий обработки ошибок выглядит следующим образом:

int DoA() 
{
 if (location == hellInAHandcart)
  return ERROR;
 else
  RETURN OK;
}

int DoB()
{
  int err = DoA();
  if (err != OK)
     return err;
  else
     return DoSomethingElse1();
}

int DoC()
{
  int err = DoB();
  if (err != OK)
     //Handle My error here in whatever way...
}

Пока в С++...

void DoA() 
{
 if (location == hellInAHandcart)
  throw Exception("Gone To Hell in a Handcart");
}

void DoB()
{
  DoA();
  DoSomethingElse1();
}

void DoC()
{
  try
  {
    DoB();
  }
  catch (Exception &E)
  {
    // Handle My error here in whatever way...
  }
}