Дизайн класса исключения C++ [закрывается]

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

42
задан Peter Mortensen 1 October 2018 в 17:53
поделиться

5 ответов

Use a shallow hierarchy of exception classes. Making the hierarchy too deep adds more complexity than value.

Derive your exception classes from std::exception (or one of the other standard exceptions like std::runtime_error). This allows generic exception handlers at the top level to deal with any exceptions you don't. For example, there might be an exception handler that logs errors.

If this is for a particular library or module, you might want a base specific to your module (still derived from one of the standard exception classes). Callers might decide to catch anything from your module this way.

I wouldn't make too many exception classes. You can pack a lot of detail about the exception into the class, so you don't necessarily need to make a unique exception class for each kind of error. On the other hand, you do want unique classes for errors you expect to handle. If you're making a parser, you might have a single syntax_error exception with members that describe the details of the problem rather than a bunch of specialty ones for different types of syntax errors.

The strings in the exceptions are there for debugging. You shouldn't use them in the user interface. You want to keep UI and logic as separate as possible, to enable things like translation to other languages.

Your exception classes can have extra fields with details about the problem. For example, a syntax_error exception could have the source file name, line number, etc. As much as possible, stick to basic types for these fields to reduce the chance of constructing or copying the exception to trigger another exception. For example, if you have to store a file name in the exception, you might want a plain character array of fixed length, rather than a std::string. Typical implementations of std::exception dynamically allocate the reason string using malloc. If the malloc fails, they will sacrifice the reason string rather than throw a nested exception or crashing.

Exceptions in C++ should be for "exceptional" conditions. So the parsing examples might not be good ones. A syntax error encountered while parsing a file might not be special enough to warrant being handled by exceptions. I'd say something is exceptional if the program probably cannot continue unless the condition is explicitly handled. Thus, most memory allocation failures are exceptional, but bad input from a user probably isn't.

24
ответ дан 26 November 2019 в 23:57
поделиться

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

Другие не менее полезные советы по усилению site

7
ответ дан 26 November 2019 в 23:57
поделиться

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

Это позволяет избежать проблем, связанных с управлением памятью сгенерированного исключения (если вы бросили указатели) и с возможностью нарезки объектов (если вы перехватываете исключения по значению).

4
ответ дан 26 November 2019 в 23:57
поделиться

Хороший дизайн - не создавать набор классов исключений - просто создайте по одной для каждой библиотеки на основе std :: exception.

Добавить информацию довольно просто:

try {
  ...
}
catch( const MyEx & ex ) {
   throw MyEx( ex.what() + " more local info here" );
}

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

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

Об этом уже спрашивали раньше, Думаю, но сейчас не могу найти.

2
ответ дан 26 November 2019 в 23:57
поделиться


2: Нет, вы не должны смешивать пользовательский интерфейс (= локализованные сообщения) с программной логикой. Общение с пользователем должно осуществляться на внешнем уровне, когда приложение понимает, что не может справиться с проблемой. Большая часть информации в исключение - это слишком много деталей реализации, чтобы их все равно показывать пользователю.
3: Используйте для этого boost.exception
5: Нет, не делай этого. См. 2. Решение о регистрации всегда должно быть на сайте обработки ошибок.

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

7
ответ дан 26 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: