2008-10-23 6 views
29

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

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

ответ

41

Герб Саттер и Александреску КНИГА C++ Coding Standards поставляется с целой главе о Обработка ошибок и исключений включая

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

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

+1

Ницца. Я добавил это в мой список покупок. (И я тоже проголосую за этот ответ, как только я смогу проголосовать снова. :-)) – 2008-10-23 19:52:58

+1

+1, из-за названия источника и сводки пули. – paercebal 2008-10-23 20:10:10

6

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

+0

Хорошая статья, спасибо. (Сегодня у меня нет голосов, я проголосую за это через несколько часов.) – 2008-10-23 19:46:54

4

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

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

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

В 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... 
} 

В то время как в C++ ...

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... 
    } 
} 
13

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

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

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

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

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

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

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

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

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