|
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
|
|
Наследование от std::exception06.11.2019, 14:11. Показов 8941. Ответов 29
Метки нет (Все метки)
Приветствую всех. Создаю библиотеку классов и в некоторых (исключительных) случаях планирую кидать исключения. Скажите, имеет ли смысл класс исключения наследовать от std::exception? Если имеет, то укажите, пожалуйста, причины.
0
|
|
| 06.11.2019, 14:11 | |
|
Ответы с готовыми решениями:
29
Обработка исключений типа std::exception Unhandled exception at 0x7c812a5b : Microsoft C++ exception: std::bad_alloc at memory location 0x0012f350 Создание своего класса исключений, наследование std::exception |
| 10.11.2019, 18:14 | |
|
0
|
|
|
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
|
|||||
| 10.11.2019, 20:44 [ТС] | |||||
|
0
|
|||||
|
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
|
|||||
| 10.11.2019, 23:52 | |||||
|
Вы не читали мое сообщение? at(), кидающийся исключением, используется во много-много раз реже, чем operator[], который их не кидает. В чем же тут выражается "ладно, хорошо"? По-моему множество программистов, чей код я видел, и я сам, уже давно проголосовали действием. Просто прочитайте еще раз мое прошлое сообщение.В момент проектирования стандартной библиотеки в будущее заглянуть было проблематично, а из С++ фичи выпиливаются с достаточно большой неохотой. И если у нас нет железобетонной причины удалить что-то, это никто делать не будет. А в случае с методом at() одного лишь "редко кому надо, т.к. обычно диапазон индексов проверяет вышестоящая функция" недостаточно, чтобы удалить метод at из библиотеки.operator[] бросающим исключение. А разработчики стандартной библиотеки этого не делали - их operator[] ничего не кидает, в отладочной версии там срабатывает assert, как уже было сказано. А то, что в составе библиотеки есть другой метод, который исключение бросает - ничего не значит в отрыве от задачи. Безотносительно того, что, как я уже сказал, он не особо пользуется популярностью. В стандартной библиотеке есть стандартное оправдание для таких решений - оправдание простое - она стандартная, и поэтому старается давать инструменты для широкого круга задач, а ваша библиотека специализирована предметной областью, в рамках которой вы пишете код. Дополнительно, у вас нет ограничений стандартной библиотеки, и вы при разработке можете учесть накопленный опыт и не делать глупостей, особенно с учетом того, что сфера применения вашей библиотеки априори уже, чем стандартной. Ну и, наконец, если бы вы действительно осознанно решили, что ваше решение с исключением правильное, то наверное смогли бы это дело обосновать? Если вы не можете обосновать свое тех. решение, значит решение не было проработано, а в инженерной деятельности - это ведет к большим проблемам, знаете ли И лично я в своих проектах никогда не использую метод at у вектора, именно по той причине, что я не знаю таких задач, на которых он лучше бы справился, чем оператор[], а значит я не могу обосновать, что мне нужен метод at, а раз я не могу это обосновать, значит он мне не нужен. Логика тут простая. При этом мне хватает ума предположить, что то, что я не знаю таких задач, не означает, что их нет в природе. Поэтому я не буду кричать, что разработчики std идиоты, потому что сделали бесполезный метод.Теперь вам для себя надо решить, нужен ли вам метод индексации проверяющий диапазон на каждом обращении и бросающий исключение, или нет, а не пытаться запомнить правила "туда ходи" и "сюда не ходи". Я вам не правила выше озвучивал, а к здравому смыслу вашему обращался, к анализу вашей предметной области и потребностей вашего проекта.
1
|
|||||
|
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
|
||||
| 11.11.2019, 00:23 | ||||
|
Зачастую попросту отказываются от одной библиотеки в пользу другой только потому что та другая не кидает исключений или наоборот. at() был задуман еще с самого начала когда ее писал Степанов и тот другой?Меня почему-то не покидает ощущение, что где-то оглядывались на Джаву.
0
|
||||
|
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
|
||
| 11.11.2019, 00:29 | ||
![]() И ответ - нет. Метода at в достандартной реализации от HP не было.
1
|
||
|
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
|
||
| 11.11.2019, 01:00 | ||
|
0
|
||
|
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
|
||
| 11.11.2019, 09:35 | ||
|
Если удастся найти текст документа WG21/N0527, то можно будет ответить точнее.
1
|
||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 11.11.2019, 15:20 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Сообщение было отмечено DrOffset как решение
Решениеи как с ними нужно работать.
есть 3 класса ошибок: 1. ошибка пользовательского ввода.
это когда, например, просишь пользователя ввести цифры, а он вводит буквы. с точки зрения программы эта ситуация вообще не является ошибкой. программа просто должна проверять всё, что вводит пользователь, и адекватно реагировать на некорректный ввод. 2. исключительная ситуация.
исключительная ситуация - это ситуация, в которой даже корректно написанный код не может гарантировать успех работы. например, нужно записать данные на диск. код программы то написан правильно, но где гарантии что на диске есть место? или нужно сделать запрос в базу данных. но вдруг в этот самый момент случился дисконнект, и с базой физически нет связи? главной особенностью любой исключительной ситуации является то, что пока не попробуешь, невозможно заранее предсказать, получится ли успешно выполнить операцию или нет. по этой причине, если функция может спровоцировать исключительную ситуацию, результат её работы в обязательном порядке нужно проверить. что не так с этим кодом?
что, если сразу же после успешного подключения, произошел дисконнект, и теперь физически с базой нет связи? в этом случае метод connect.query(request); потерпит неудачу.однако алгоритм продолжит работу так, словно всё хорошо. может быть крашнется где нибудь дальше по тексту. и хорошо, если данные при этом не попортит. правильный код:
что не нужно на каждый чих писать очередной ifно главная его киллер-фича в том, что в случае неудачи гарантируется, что алгоритм не будет продолжать выполнение с некорректными данными.
или что-то в таком духе. другая киллер-фича эксепшенов заключатеся в том, что можно построить отказоустойчивую архитектуру, не зная, и даже не вникая в детали реализации используемых компонентов (библиотек, классов, и тп) это - обширная тема. тянет на отдельную сейчас я не буду в неё углубляться. 3. программная ошибка.
неправильно написанный код. программист напортачил. например, распространенная ошибка новичка:
i <= size приводит к выходу за пределы диапазона.в лучшем случае будет краш. в худшем - отработает на неконсистентных данных. что можно сделать с такой ошибкой? исключение бросать бесполнезно. исключение предотварит UB, но сам алгоритм от этого рабочим не станет. то есть, программа как не работала, так и будет дальше не работать. на самом деле единственный способ решения проблемы - позвать программиста, и пускай исправляет баг. программные ошибки - это тот случай, когда нужно стремиться, что бы ошибок вообще не не было, а не пытаться бороться с последствиями. для этого применяют техники привентивной защиты от ошибок: 1. assert идея настолько же проста, насколько гениальная: есть две конфигурации сборки: дебаг (отладочная) и релиз (окончателньая версия) в дебаге присутствуют и исполняются все ассерт-проверки. а вот в релизную сборку ассер-проверки не входят. (они вообще не участвуют в компиляции) поэтому, можно наколбасить 100500 различных проверок на каждый чих, не боясь снижения производительности. всё равно всё эти проверки не войдут в релиз. таким образом, всё что нужно - это запустить и потестить отладочную версию. если всё хорошо - собираем уже проверенный и шустрый релиз. существует обратная зависимость количества багов от количества ассертов. чем больше ассертов, тем меньше багов. чем меньше ассертов, тем больше багов. особо продвинутые люди приспособили ассерты для контрактного программирования. пример:
который сразу уменьшит количество багов этак на 95% ассерты делают код более читабельным. сразу видны ограничения, и каким ожидается результат. 2. авто-тесты например, организация поставила перед тобой очень важную и отвественную задачу: нужно сделать функцию, которая принимает два целых числа и возвращает их сумму:
как минимум, нужно убедиться, что код вообще компилируется. далее, убедиться, что функция работает как ожидается для этого ты можешь сделать отдельный маленький проект, где проиллюстрируешь использование функции:
а значит можешь написать код, который проверит правильно ли работает твоя функция. такой отдельный мини-проектик, который контролирует корректность работы функционала, называется "юнит-тестом" суть идеи в том, что бы покрыть весь свой код юнит-тестами. и запускать их каждый раз при любых изменениях в проекте. если где что сломал, тесты это покажут. после успешного прохождения всех тестов, уже можно смело собирать релизную сборку. 3. пожалуй самая мощная техника. смысл техники в том, что бы изначально проектировать свои функции таким образом, что бы их нельзя было использовать неправильно. пример плохого кода (уровень: новичок):
это - контракт между функцией и программистом. в данном случае функция говорит: "я прошу указатель в качестве аргумента" а значит программист может подсунуть любой указатель типа const game_object* а значит, казалось бы, он имеет полное право подсунуть nullptr,что скорее всего приведет к аварии (access violation) пример плохого кода (уровень: балбес):
балбес указал в документации, что нужно передавать указатель на реальный объект. нулевые указатели запрещены. запрет на нулевые указатели конктролирует ассерт. а значит, если даже ничайно передать nullptr,то отладочная сборка сразу же покажет проблему. вроде бы все хорошо. на самом деле не всё хорошо. почему я назвал код плохим, а его автора балбесом? потому что этот болван на ровном месте сам себе создал проблему, а потом начал героически её преодолевать. вот так должен выглядеть нормальный код:
используй специально предназначенные для этого ссылки. уже не получится передать nullptrи не нужно дополнительно ничего проверять. или такой пример: пользователя просят ввести цифры, а он вводит буквы. приходится дополнительно проверять корректность введеных им данных. но что, если просто физически запретить вводить с клавиатуры что либо, кроме цифр? в этом случае ошибка ввода в принципе не сможет возникнуть:
и ты привентивно уберешь себя и своих юзеров от ошибок. а во-первых, когда пишешь код, всегда задай себе следующие вопросы: 1. что здесь может пойти не так? например, индекс за пределами диапазона. 2. как можно идентифицировать наличие проблемы? например, проверить индекс на максимально допустимый. 3. самое главное(!) что делать теперь с этой проблемой? вот ты предлагаешь использовать эксепшены.
ок, допустим, оператор[] бросил эксепшен.Вася в своём коде благополучно поймал это исключение. что дальше? как это поможет? никак. некорректный алгоритм работать не будет. и никакими эксепшенами это не исправить. кто-то сейчас обязательно вспомнит про метод std::vector::atну так вот, я не знаю кто и зачем его завёз в язык, но на практике он бесполезен. если приложение было недостаточно хорошо протестированно, метод at() не спасет. а если хорошо - то он попросту не нужен. кто-то скажет: режим "паранойи". параноики не любят ассерты за то, что те выпиливаются из релиза. вместо ассертов они либо используют эксепшены во все поля, либо используют идиому raise raise в дебаге ведет себя как обычный assert, а в реализе - кидается эксепшенами.
лучше пусть снижается быстродействие и растет расход памяти, главное, что бы никакая ошибка не была ничайно пропущена. используется либо балбесами, у которых паранойя головного мозга. либо это - реальные требования к надежности продукта с повышенной ответственностью. пример: есть торговый сервер. он обеспечивает работу московской биржи. там за один только рабочий день крутится столько грошиков, сколько наши олигархи за год не зарабатывают. твоя задача несложная, но очень ответственная: нужно написать малюсенький простенький плагин (dll), ничего особенного. но если твой плагин крашнется, он потянет за собой весь процесс. и если торговый сервер упадет в самый разгар рабочего дня... короче, твоя главная задача обеспечить отказоустойчивость, и уже только затем, собственно, реализовывать бизнес-логику. в таких условиях я бы, например, вынес функционал плагина в отдельный сервис. если даже мой сервис после всех отладок и тестов упадёт на бою, это всё равно никак не затронет соседний торговый сервер. а значит я могу спать спокойно. а иной балбес будет использовать at(), молиться и поститься.
4
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
|
|
| 20.11.2019, 18:38 [ТС] | |
|
hoggy, это было мощно!!! Спасибо за ликбез!!!
0
|
|
|
Неэпический
|
|
| 20.11.2019, 19:44 | |
|
0
|
|
| 20.11.2019, 19:44 | |
|
Помогаю со студенческими работами здесь
30
Выдаёт ошибку "Unhandled exception at 0x00007F exception: std::bad_alloc in memory location" Вылетает на std::length_error exception Грамотно обработать ошибку std::exception
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога
Финальные проекты на Си и на C++:
hello-sdl3-c. zip
hello-sdl3-cpp. zip
Результат:
|
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога
MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает
монорепозиторий в котором находятся все исходники.
При создании нового решения, мы просто добавляем нужные проекты
и имеем. . .
|
|
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение:
В этой книге («Подход, основанный на вариантах использования») Ивар утверждает,
что архитектура программного обеспечения — это
структуры,. . .
|
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога
Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
|
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip
На первой гифке отладочные линии отключены, а на второй включены:. . .
|
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем.
. . .
|