277 / 154 / 52
Регистрация: 30.06.2011
Сообщений: 1,703
1

Наследование от std::exception

06.11.2019, 14:11. Показов 3301. Ответов 29
Метки нет (Все метки)

Приветствую всех. Создаю библиотеку классов и в некоторых (исключительных) случаях планирую кидать исключения. Скажите, имеет ли смысл класс исключения наследовать от std::exception? Если имеет, то укажите, пожалуйста, причины.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.11.2019, 14:11
Ответы с готовыми решениями:

Обработка исключений типа std::exception
Пытаюсь выполнить участок кода: try { socket_=new Network::ClientSocket(Host,Port); } catch...

Unhandled exception at 0x7c812a5b : Microsoft C++ exception: std::bad_alloc at memory location 0x0012f350
что то я запутался совсем. подскажите где глюк? Считываю из XML данные: char*...

Создание своего класса исключений, наследование std::exception
хотел создать свой класс исключений пронаследовав от std::exception, но немного запутался в...

Unhandled exception at at 0x75E717D2 in ConsoleApplication24.exe: Microsoft C++ exception: std::out_of_range at memory l
Здравствуйте, помогите пожалуйста, при проходе через последний цикл выдаёт вот такую ошибку:...

29
Эксперт С++
8563 / 4137 / 910
Регистрация: 15.11.2014
Сообщений: 9,339
07.11.2019, 12:05 2
Цитата Сообщение от d7d1cd Посмотреть сообщение
Скажите, имеет ли смысл класс исключения наследовать от std::exception?
в твоём случае - нет, не имеет.
потому что тебе вообще не нужны собственные классы эксепшенов.

используй стандартные: std::logic_error, std::runtime_error, etc
0
277 / 154 / 52
Регистрация: 30.06.2011
Сообщений: 1,703
07.11.2019, 14:59  [ТС] 3
Цитата Сообщение от hoggy Посмотреть сообщение
потому что тебе вообще не нужны собственные классы эксепшенов. используй стандартные
Ну как то, вроде, делается стильная, модная, молодежная библиотека со всеми своими классами (в том числе строками и числами), а исключения пользователю приказать ловить стандартно? Не хорошо... Многие библиотеки классов (VCL, FMX, например) не используют стандартные классы исключений. Свои имеют. Чем мы хуже?
Кроме этого, мало мне в качестве информации об исключении одного текстового поля.
0
6740 / 4538 / 1840
Регистрация: 07.05.2019
Сообщений: 13,725
Записей в блоге: 1
07.11.2019, 15:37 4
Цитата Сообщение от d7d1cd Посмотреть сообщение
Ну как то, вроде, делается стильная, модная, молодежная библиотека со всеми своими классами (в том числе строками и числами), а исключения пользователю приказать ловить стандартно? Не хорошо... Многие библиотеки классов (VCL, FMX, например) не используют стандартные классы исключений. Свои имеют. Чем мы хуже?
Кроме этого, мало мне в качестве информации об исключении одного текстового поля.
Унаследуйся, хуже точно не будет. Тогда хотя бы твоё исключение можно будет отловить по std::exception
0
Эксперт С++
8563 / 4137 / 910
Регистрация: 15.11.2014
Сообщений: 9,339
07.11.2019, 16:51 5
Цитата Сообщение от d7d1cd Посмотреть сообщение
а исключения пользователю приказать ловить стандартно? Не хорошо...
всегда стандартно.
даже если это кастомные эксепшены.
их всё равно всегда ловят стандартным образом:

C++
1
2
3
4
5
6
7
8
try
{
    work();
}
catch(const ::std::exception& e)
{
    std::cerr << e.what();
}
если эксепшен не отнаследован от std::exception,
это такой красноречивый признак делитанта,
который пишет ненадежный код.

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

об этом пара слов поподробнее:

что не так с этим кодом?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
try
{
    if(!load_image(file))
        throw ::std::runtime_error( 
            "can not load file '" + 
            ::std::string(file) + 
            "'"
        );
}
catch(const ::std::exception& e)
{
    ::std::cerr << e.what() << ::std::endl;
}
для того что бы бросить эксепшен, его нужно сначала сконструировать.
при конструировании используется выражение std::string(file),
которое в свою очередь тоже может бросить исключение.
и тогда вместо рантайма полетит бадаллок.
таким образом, вместо вменяемой диагностики,
можно неиллюзорно схлопотать нежданчик,
который замаскирует исходную проблему.

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

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

Цитата Сообщение от d7d1cd Посмотреть сообщение
(VCL, FMX, например)
нашел на кого ровняться.

тупиковая ветвь в эволюции
я вот даже не знаю, что у них там под капотом.

второе - даже не гуглится.
2
277 / 154 / 52
Регистрация: 30.06.2011
Сообщений: 1,703
07.11.2019, 22:17  [ТС] 6
hoggy, я читал твои сообщения в других темах, поэтому понимаю, что тягаться с тобой в знании С++ себе дороже . Спасибо за развернутый ответ.
То есть, даже если я создам свой класс исключения, унаследовавшись от std::exception, передаваемые в исключении значения в программе должны быть константами?


Цитата Сообщение от hoggy Посмотреть сообщение
тупиковая ветвь в эволюции. я вот даже не знаю, что у них там под капотом.
Почему тупиковая? Embarcadero поддерживает эту библиотеку.
Кстати, их базовый класс исключений Exception не унаследован от std::exception.

Цитата Сообщение от hoggy Посмотреть сообщение
второе - даже не гуглится.
https://ru.wikipedia.org/wiki/FireMonkey
0
d7d1cd
08.11.2019, 08:34  [ТС]
  #7

Не по теме:

Отредактировали мое последнее сообщение и даже не сообщили об этом... Что за беспредел? Что я нарушил?

0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
08.11.2019, 12:30 8
Цитата Сообщение от d7d1cd Посмотреть сообщение
Почему тупиковая?
Цитата Сообщение от d7d1cd Посмотреть сообщение
Кстати, их базовый класс исключений Exception не унаследован от std::exception.
Сами спросили сами и ответили?)
Уже лучше библиотеку писать вообще без исключений, что кстати и часто делают.
Цитата Сообщение от d7d1cd Посмотреть сообщение
Embarcadero поддерживает эту библиотеку.
Ну любят люди труп пинать и что дальше?
0
фрилансер
3212 / 2409 / 617
Регистрация: 11.10.2019
Сообщений: 7,204
08.11.2019, 13:12 9
не знаю, как другим, а лично меня раздражают библиотеки/функции, которые швыряются исключениями. На кой они мне? Только код загромождать. Мне вполне достаточно возврата false/код ошибки /текст ошибки
0
277 / 154 / 52
Регистрация: 30.06.2011
Сообщений: 1,703
08.11.2019, 13:24  [ТС] 10
Цитата Сообщение от Алексей1153 Посмотреть сообщение
не знаю, как другим, а лично меня раздражают библиотеки/функции, которые швыряются исключениями. На кой они мне? Только код загромождать. Мне вполне достаточно возврата false/код ошибки /текст ошибки
Я не говорю, что надо пихать исключения везде и всюду. Но есть ситуации, когда без исключения не вижу выхода. Пример. Есть класс строки. Запрашивается индекс несуществующего элемента через оператор []. Как обойтись без исключения?
C++
1
2
CastomString str = "Hello";
char s = str[70]; // Что тут должно произойти без исключения?
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
08.11.2019, 13:31 11
Цитата Сообщение от d7d1cd Посмотреть сообщение
Как обойтись без исключения?
Бить по рукам.
И того кто хотел сделать чтобы оператор [] исключения бросал - тоже.
1
фрилансер
3212 / 2409 / 617
Регистрация: 11.10.2019
Сообщений: 7,204
08.11.2019, 14:01 12
Цитата Сообщение от d7d1cd Посмотреть сообщение
Запрашивается индекс несуществующего элемента
я привык проверять границы массивов, ну а если забыл - мне отладчик в нужном месте и так носом тыкнет и я подправлю )
0
Эксперт С++
8563 / 4137 / 910
Регистрация: 15.11.2014
Сообщений: 9,339
08.11.2019, 15:17 13
Цитата Сообщение от d7d1cd Посмотреть сообщение
Я не говорю, что надо пихать исключения везде и всюду. Но есть ситуации, когда без исключения не вижу выхода. Пример. Есть класс строки. Запрашивается индекс несуществующего элемента через оператор []. Как обойтись без исключения?
это очень красноречиво-показательная ситуация, когда исключения не нужны.

ты вообще понимаешь, зачем нужны исключения?
0
277 / 154 / 52
Регистрация: 30.06.2011
Сообщений: 1,703
08.11.2019, 15:45  [ТС] 14
Цитата Сообщение от hoggy Посмотреть сообщение
ты вообще понимаешь, зачем нужны исключения?
Теперь уже не знаю... Расскажите.

И никто из 3-х человек не сказал что делать, если возникает ситуация в приведенном выше примере.

Добавлено через 50 секунд
Цитата Сообщение от Алексей1153 Посмотреть сообщение
я привык проверять границы массивов, ну а если забыл - мне отладчик в нужном месте и так носом тыкнет и я подправлю )
Это какой отладчик показывает выход за границы массива?
0
фрилансер
3212 / 2409 / 617
Регистрация: 11.10.2019
Сообщений: 7,204
08.11.2019, 15:55 15
d7d1cd, не во всех, конечно, случаях. Но выход за край вектора почти всегда вызывает краш (отладчик покажет место краша и состояние переменных). В остальных я увижу кривую работу алгоритма и так же буду разбираться в отладчике
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
08.11.2019, 16:09 16
Цитата Сообщение от d7d1cd Посмотреть сообщение
Расскажите.
Ну, вот допустим я как обычный белый человек имею массив чисел - 1, 2, 3, 4, 5, 6, 7.
У меня есть какой-то контейнер в котором я храню эти значения. И вот мне надо сделать какие-то вычисления (сложить, умножить там и тд) над данными числами, я как хороший программист вынесу это в функцию:
C++
1
2
3
4
5
int calculate_values(array) noexcept {
    ...
    blah += array[i];
    ...
}
В ней мне по любому надо получить доступ к нужному мне элементу и что-то посчитать. В какой-то момент я выхожу за границы массива (что есть UB) и падаю, с огромными глазами я смотрю почему же я упал в terminate, а оказалось, что кто-то умудрился бросать исключения из оператора []. Пофиксив проблему с выходом за границы массива, я не могу оставить мой код прежним..
Мне надо все обращения к оператору [] оборачивать в try-catch блок и я надеюсь его исключения отнаследованы от std::exception иначе бить уже можно выше рук. И мой пример уже выглядит так:
C++
1
2
3
4
5
6
7
int calculate_values(array) noexcept {
    ...
    try {
       blah += array[i];
    } catch (std::exception const& e) { ... }
    ...
}
Или убирать noexcept спецификатор.
Любой из этих вариантов плохой и несет за собой огромный оверхед, и я просто с пустого места лишаюсь части оптимизаций, а я ведь просто хотел получить элемент из массива...

Добавлено через 2 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
почти всегда вызывает краш
Не всегда, т.к. выход за пределы это UB. И если и вызывает, то это скорее работа ASAN'a.
0
15267 / 8234 / 1993
Регистрация: 30.01.2014
Сообщений: 14,015
08.11.2019, 16:13 17
Цитата Сообщение от d7d1cd Посмотреть сообщение
Что тут должно произойти без исключения?
assert должен сработать. Ибо это не исключительная ситуация, а просто ошибка программиста.
1
277 / 154 / 52
Регистрация: 30.06.2011
Сообщений: 1,703
09.11.2019, 18:42  [ТС] 18
Azazel-San, так зачем оборачивать в try-catch? Ошибка выхода за пределы массива найдена же. По сути, исключение в операторе [] для этого и бросалось: чтобы указать, что где-то происходит выход за пределы массива...
Но теперь DrOffset указал, что это не исключительная ситуация, а ошибка программиста и показал как надо поступать в таком случае. Спасибо!
Но по исключениям все равно вопрос. Например, метод at std::vector при выходе бросает исключение. Но ведь это не исключительная ситуация, а ошибка! Почему тогда бросается исключение?
0
15267 / 8234 / 1993
Регистрация: 30.01.2014
Сообщений: 14,015
09.11.2019, 19:24 19
Цитата Сообщение от d7d1cd Посмотреть сообщение
метод at std::vector при выходе бросает исключение.
Цитата Сообщение от d7d1cd Посмотреть сообщение
Но ведь это не исключительная ситуация, а ошибка! Почему тогда бросается исключение?
Потому что так захотел разработчик библиотеки. В данном случае для метода at выход за пределы диапазона рассматривается как исключительная ситуация.

Предчувствуя у вас когнитивный диссонанс сразу скажу, что нет особого смысла выяснять эти вещи в отрыве от проекта. Возможно мы можем найти такую область, где выход за пределы вектора можно рассматривать как исключительную ситуацию, и тогда нам понадобится vector::at вместо vector::operator[]. Однако по моему опыту я применял vector::at ровно 0 (ноль) раз. Т.е. в моей практике не было достаточно весомых случаев для применения этого кейса.

Добавлено через 2 минуты
Цитата Сообщение от d7d1cd Посмотреть сообщение
Ошибка выхода за пределы массива найдена же. По сути, исключение в операторе [] для этого и бросалось: чтобы указать, что где-то происходит выход за пределы массива...
Ну нет. Раз мы решили, что у нас тут исключительная ситуация, значит мы должны ее обработать. Чтобы просто найти ошибку - достаточно assert`а или другого подобного механизма. Исключительная ситуация - это такая, которая хоть и выбивается из нормального выполнения программы, но, тем не менее, вписывается в ее логику. Ошибки же программиста в логику не вписываются.
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
09.11.2019, 23:48 20
Цитата Сообщение от d7d1cd Посмотреть сообщение
Azazel-San, так зачем оборачивать в try-catch?
Ну, как бы если что-то бросает исключение, то Вы должны его обработать.
Конечно, для данного тривиального примера Вы, в своих проектах вольны делать что угодно и не ловить исключений, но если речь заходит об использовании такого кода другими, в качестве, например, библиотеки, то такое поведение уже не позволимо. Вы же не знаете кто, как и где будет использовать вашу библиотеку, Вы должны предусмотреть все варианты. Даже под всякими нагрузками, поведение кода может меняться.
Представьте лица тех разработчиком приложение которых начало падать из-за того что ваша библиотека где-то не обрабатывает исключения..
Цитата Сообщение от d7d1cd Посмотреть сообщение
Но теперь DrOffset указал, что это не исключительная ситуация, а ошибка программиста и показал как надо поступать в таком случае.
assert - это хорошо, но на самом деле он не защищает от всех видов ошибок программиста и/или правильности поведения логики его кода. Тем более не факт, что этот assert будет там где вы его ожидаете, поэтому для предотвращения своих ошибок я бы воспользовался ЮТ, которые дадут больше гарантий.
Это скорее отличный инструмент который в некоторых моментах и расставленный в нужных местах может сохранить много времени, но я бы не стал только на него полагаться или злоупотреблять им.
Цитата Сообщение от d7d1cd Посмотреть сообщение
Но ведь это не исключительная ситуация, а ошибка!
Значит разработчики стандартной библиотеки решили иначе, вообще похоже этот метод был таким задуман еще изначально когда ее писал Степанов.
Цитата Сообщение от d7d1cd Посмотреть сообщение
Почему тогда бросается исключение?
Вдохновлялись Джавой? Вообще интересно для чего был придуман этот метод и какой функционал в него вкладывали. Был ли он изначально или его позже добавили через пропозал? Если кто и знает, то только DrOffset
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.11.2019, 23:48

Выдаёт ошибку "Unhandled exception at 0x00007F exception: std::bad_alloc in memory location"
Добрый день, друзья не могли бы помочь разобраться, почему выдаёт такую ошибку? Вот #include...

Вылетает на std::length_error exception
название не очень отражает суть вопроса, но лучше я предумать не смог. Есть программа собранная в...

Грамотно обработать ошибку std::exception
struct Node { Node(int data): data_(data) {} int data_; // полезная часть списка ...

Ошибка при работе с std::exception*
Почему в случаях 1 и 3 выводится нормальный e.what(), а во втором - ошибочный? Как это исправить? ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.