0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47
|
||||||
1 | ||||||
Исключения при вызове конструктора копирования27.09.2024, 20:20. Показов 823. Ответов 5
Метки нет (Все метки)
Добрый день, уважаемые! вопрос по поводу исключений. Нужно ли в следующем коде, вызов метода createBike() на строчке 10, оборачивать в блок try{}?
я делаю move объекта bike, в методе createBike(), и тем самым вызываю конструк перемещения у объекта Bike. Конструктор перемещения класса Bike может кидать исключение(он НЕ noexcept). P.S. Я знаю, что не стоит мувать объект bike, ибо без move, там будет NRVO, но я сделал move только ради примера. Тут акцент на обработке исключений. Вопрос номер 2. Часто вижу, как на гитхабе, у хороших опен-сорс проектов, написанных на C++, не используется блок try-catch(точнее, мало где в коде). Например, в std::stack есть методы, как pop() или top(). Если у std::stack вызвать метод top(), будет возвращен по значению верхний элемент стека. Но, что если stack хранит пользовательский тип, чей конструктор копирования может кинуть исключение? то есть при вызове stack.top(), мы можем получить исключение. Но почему-то никто не оборачивает stack.pop() в конструкцию try{}.
0
|
27.09.2024, 20:20 | |
Ответы с готовыми решениями:
5
Ошибка при вызове конструктора копирования Исключения при вызове throw Зачем двоеточие при вызове конструктора? Крашится приложение при вызове конструктора |
Вездепух
12792 / 6669 / 1795
Регистрация: 18.10.2014
Сообщений: 16,881
|
|
27.09.2024, 22:14 | 2 |
Сообщение было отмечено NewFive как решение
Решение
Так (отвечая на оба вопроса), а откуда у вас возникла идея оборачивать в
try{} именно непосредственно вызов бросающей исключение функции? Зачем? try{} пишется ради catch , то есть ради обработки исключений. Вы готовы здесь его обрабатывать? Если нет, то и никакого try{} здесь не нужно.Вся идея структурной обработки исключений - это то, что обрабатывать исключения нужно именно там, где вы хотите/готовы их обрабатывать. В общем случае это будет где-то весьма и весьма далеко и намного выше по стеку вызовов, чем то место, в котором исключение возникло. А на всех более низких вложенных уровнях кода вам не нужен никакой try{} . Вам нужно лишь обеспечить корректное "сворачивание" кода (освобождение ресурсов и т.п.) если из него вдруг выбросится исключение или есть через него вдруг будет "пролетать" исключение выброшенное где-то внизу (и летящее куда-то наверх).Временно перехватывать исключения в середине их полета к цели тоже может иметь смысл: чтобы добавить в исключение какую-то полезную информацию о контексте, в котором оно произошло, а затем пинком под зад (при помощи throw; ) послать его дальше в полет наверх, в направлении конечной цели.То есть тот самый try{} - он где-то есть. Но не здесь. Он сделан где-то намного выше и более огульно охватывает более крупные участки кода. А здесь, прямо на вызове stack.pop() он просто нинафиг не нужен. Что вы собрались делать в catch именно тут?Разумеется, если try{} вообще нет ни на каком уровне, то исключение вылетит за пределы main и программа аварийно завершится. Ну так может авторы кода этого и хотели?
2
|
3718 / 2647 / 761
Регистрация: 29.06.2020
Сообщений: 9,800
|
|
28.09.2024, 13:10 | 3 |
0
|
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47
|
||||||
29.09.2024, 16:04 [ТС] | 4 | |||||
Спасибо больше за ответ, понял Вас.
А как в промышленной разработке поступают(на примере кода ниже), если было выброшено исклчюение, а у объекта была обеспечена только базовая гарантия исключений? 1. дают аварийно завершиться программе 2. ловят исключение и сами завершают программу 3. ловят исключение и продолжают выполнение программы? К примеру, я хочу вызвать конструктор копирования у объекта vec2 типа std::vector от другого объекта vec1 типа std::vector. Но в конструкторе копирования вылетело исключение, затем были освобождены все ресурсы(чтобы объект vec1 остался в валидном/консистентном состоянии) и затем исключение из конструктора копирования было проброшено дальше. Я поймал его где-то сверху, что дальше мне делать? 1. Поймать исключение и завершить программу, написав в логах о том, что случилось 2. Поймать исключение, написать в логах о том, что случилось и дальше продолжать выполнение программы(но а если мы воспользуемся случайно vec1 ? это же неопределенное поведение программы, так делают в промышленной разработке ?). 3. Вообще не ловить исключине и дать программе аварийно завершиться.
0
|
3718 / 2647 / 761
Регистрация: 29.06.2020
Сообщений: 9,800
|
|
29.09.2024, 16:32 | 5 |
NewFive, всё зависит от того можете ли вы логично обработать исключение.
Если нет, тогда логирование и аварийное завершение. Если можете, прерываете текущую задачу, сообщаете об ошибке и продолжаете работу программы. Это всё только логическая организация вашей программы. Например вы редактируете какой-то документ, пытаетесь сохранить, получаете исключение, ловите сообщаете об ошибке и продолжаете работу. И так далее. Сама программа разбивается на подзадачи и родительский код отвечает за часть исключений, которые может обработать. И так далее, по цепочке вверх.
1
|
0 / 0 / 0
Регистрация: 13.12.2019
Сообщений: 47
|
|
30.09.2024, 12:14 [ТС] | 6 |
SmallEvil понял, спасибо!
0
|
30.09.2024, 12:14 | |
30.09.2024, 12:14 | |
Помогаю со студенческими работами здесь
6
Ошибка при вызове конструктора с параметрами Seg fault при вызове конструктора Что за ошибка при вызове конструктора? В чём отличия конструктора копирования и конструктора перемещения? Где и как их нужно использовать? Запуск конструктора копирования при возврате по значению Пояснение к аргументам при вызове функции, и запрет конструктора по умолчанию Ошибка при вызове конструктора basic_regex в конструкторе std::sregex_iterator Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |