![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Ну если на данном уровне можно обработать 20 исключений, нужно их обрабатывать - у Страуструпа это же четко обозначено. Но если в одном месте вылетает 20 разнотипных исключений то это проблема архитектуры, но не самих исключений. Потому что это значит, что в кучу смешано слишком много разного. Смысл их собирать столько на одном уровне?
|
|||
|
||||
| EvilsInterrupt |
|
|||
|
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
drug007,
Все еще продолжаем обсуждение Вопроса №4. К примеру пишется код использующий результаты методы класса парсера файла текстового формата, что может произойти? 1) Семантическая ошибка 2) Синтаксическая ошибка 3) Некорректный символ. К приму встретился не текстовой символ, такое может быть если файл не докачался 3) Ошибка ввода вывода, к примеру во время чтения файла или его открытия Построим дерево вызовов: 0) super_future(): 1) ....parser.parse() 2) ........semantic_something_doing() 3) ............syntax_something_doint() 4) ................read_char() 5) ....................open_file() 6) ....................read_file() Как в этом случае должна быть построен код по обработки ошибок? может быть брошено исключение на любом из 1-6 уровней. |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
EvilsInterrupt, в данном случае почти все исключения должны иметь одного общего предка parse_error (метод what() возвращает текст с ошибкой и местом в файле). Таким образом, вышестоящий код (уровень 0 или меньше) перехватывает только его. Этому коду, если честно, сильно фиолетово, из-за чего не удалось распарсить файл (вряд ли он будет этот файл исправлять). Главное, что распарсить не удалось, а дальше уже пусть разбирается пользователь по представленной в ошибке информации.
А вот с ошибкой ввода/вывода сложней. Она к парсингу отношения не имеет и, по хорошему, ввод вывод следует осуществлять вне парсера. Но это неудобно. В итоге, тебе необходимо сделать только два catch блока, для отлова ошибок ввода/вывода и парсинга. В принципе, если действия будут одинаковыми, то может будет иметь смысл тупо ловить std::exception и все. |
|||
|
||||
| EvilsInterrupt |
|
|||
|
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
bsa,
Ок. А что если ввести концептуальные уровни(не знаю как это проще назвать) попробую пояснить: Концептуальный уровень 1: уровни 1, 2, 3 - это уровни парсинга Концептуальный уровень 2: уровни 4, 5, 6 - это уровни ввода-вывода Тогда в коде любого из методов концептуального уровня 1 ловить брошенные исключения нижестоящего концептуального уровня 2 и бросать вместо них типы исключений относящиеся к концептуальному уровню 1. Тогда методу super_feature() достаточно будет ловить ошибки только одного концептуального уровня - парсинга. А о том что есть еще и ввода-вывода он и знать не будет. Другими словами появляются вертикальные слои, если смотреть на глубину вызовов как на направление сверху-вниз. Насколько такое применимо на практике? ЗЫ: Спрашиваю то что еще не применял на практике и это лишь мои догадки |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Имхо, вопрос не очень корректный. Это может быть применимо. Другое дело, что такое делать не стоит. |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
разнотипных исключений нужно примерно столько, сколько требуется разных реакций на них. если почти все исключения приводят к сообщению об ошибке, то польза от уровней может быть только в детализации сообщений. скорее всего оно того не стоит |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Это да, можно и больше. Но не для обработки же в одном месте! Хоть bsa и ответил уже, повторю его ответ 0) super_future(): <-------- ошибка парсинга 1) ....parser.parse() 2) ........semantic_something_doing() 3) ............syntax_something_doint() <-------- здесь только ошибка ввода-вывода 4) ................read_char() 5) ....................open_file() 6) ....................read_file() т.е. только два типа исключений мы можем здесь обработать. Более того, если это библиотека не факт, что их вообще нужно обрабатывать. Концептуальные уровни обязательно должны присутствовать - собственно разные класс, унаследованные от exception для этой цели и служат. Но обрабатывать исключение нужно только если действительно это нужно по бизнес-логике, например часть ошибки может устранена на текущем уровне, а остальное = на более высоком. Перехватывать просто с подменой класса исключения напрасная трата времени, имхо. В Вашем примере я бы перехватывал исключение ввода-вывода и выбрасывал взамен ошибку ввода-вывода только в том случае, если имя файла формируется внутри super_feature, если же параметры файла передаются извне, то и перехватывать не нужно. |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Тот, кто бросает исключение, не знает где и как оно будет обработано. Поэтому типов исключений много - для тонкой обработки. С точки зрения вызывающей стороны типов исключений (однотипных ситуаций, требующих обработки) обычно меньше. В общем случае будет несоответствие количества генерируемых и обрабатываемых типов исключений, и это решается наследованием типов исключений. Стратегия обработки сообщений может быть разной; вполне возможно и нормально для большой группы исключений иметь один обработчик. Без описания конкретной задачи и архитектуры сказать хорошо это или нет нельзя. |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Трудно не согласиться. Но я бы в любом случае избегал бы такого развития событий, какая бы архитектура и задача не была. Если уж только legacy code заставляет, либо "тяп-ляп" сделать достаточно. |
|||
|
||||
| EvilsInterrupt |
|
|||
|
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
Ок, спасибо за обсуждение по Вопросу №4.
Вопрос №5: От какого базового типа лучше всего создавать свою иерархию исключений в библиотеки? От своего или от std::exception и почему? Я видел проект, которые имел свой BaseException с методом where() в котором возвращались __LINE__, __FILE__, __FUNCTION__ . Но если честно, то на практике это не шибко может помочь, ведь если возникла ошибка, то можно поставить брякпоинт глядя на callstack в окне отладчика |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
EvilsInterrupt, в любом случае лучше наследоваться от std::exception. Так как код, который будет использовать твою либу, может понятия не иметь о твоих исключениях. Более того, в линухе есть стандартный перехватчик исключений, который поддерживает метод what у std::exception.
|
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Люди писали проект, обрабатывали исключения-наследники std::exception и тут нашли Вашу замечательную библиотеку. А у нее своя иерархия исключений и, соответственно, чтобы их обрабатывать, им придется переписывать свой код и добавлять поддержку Ваших исключений. В их глазах это может оказаться серьезным аргументом против. |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Но если очень хочется использовать свою иерархию, то можно сделать свой базовый класс наследником std::exception. В этом случае, и волки сыты, и овцы целы.
|
|||
|
||||
| EvilsInterrupt |
|
|||
|
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
Я придя в один проект увидел достаточно стройную библиотеку. Библиотека написана силами команды компании. Однако там свой собственный Exception класс, от которого наследуются все типы исключений. На вопрос: "Почему?" получаю ответ "Так исторически сложилось, лет 10 назад С++ был далеко не тем чем является сейчас. Более того даже STL был далеко от того состояния чтобы его можно было использовать в проектах". Но тут же добавили "Если бы подобный выбор стоял сейчас, конечно мы бы наследовались от std::exception". Но я не понимаю: Что в этом классе такого? Ведь есть риск смешать свои ошибки с ошибками стандартной библиотеки. |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Каким образом Вы смешаете? Класс std::exception он один такой, другого такого класса нет. Или Вы имеете в виду, что перехватывая std::exception Вы "случайно" перехватите другое исключение? Так для этого и предназначена иерархия. А если Вам надо перехватить наследника std::exception, то в начале делаете перехват наследника, а следующим делаете перехват std::exception. В нем ничего нет особенного, кроме того что он наследник для всех остальных. Не забывайте, что если Вы забудете перехватить исключение, то программа просто упадет с непонятной ошибкой (если обработчик не установите - то это нужно понимать для чего вы так делаете), а наследуясь от std::exception вы гарантируете, что все исключения будут обработаны. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |