Чому я не повинен загортати кожен блок у "спробувати" - "зловити"?


430

Я завжди був думкою, що якщо метод може кинути виняток, тоді нерозумно не захищати цей виклик за допомогою значущого блоку спробу.

Я щойно опублікував " Ви ВЖЕ завжди повинні завершувати дзвінки, які можуть робити спроби, ловити блоки. "на це питання і мені сказали, що це" надзвичайно погана порада "- я хотів би зрозуміти, чому.


4
Якби я знав, що метод кине виняток, я б виправив його в першу чергу. Це тому, що я не знаю, де і чому код буде викидати винятки, я ловлю їх у джерелі (кожен метод - один загальний пробний влов). Наприклад, команда дала мені кодову базу з попередньою базою даних. Багато стовпців бракувало та потрапляло лише після додавання спробу лову в шарі SQL. По-друге, я можу записати ім'я методу та повідомлення для налагодження в режимі офлайн, інакше я не знаю, де воно виникло.
Чакра

Відповіді:


340

Метод повинен виловлювати виключення лише тоді, коли він може впоратися з ним якось розумним чином.

В іншому випадку передайте його вгору, сподіваючись, що метод, що знаходиться вище в стеці викликів, може мати сенс.

Як зазначали інші, добре застосовувати необроблений обробник винятків (з веденням журналу) на найвищому рівні стеку викликів, щоб забезпечити реєстрацію будь-яких фатальних помилок.


12
Варто також зазначити, що на tryблоки є витрати (з точки зору генерованого коду) . В роботі "Ефективніший C ++" Скотта Майєрса є хороша дискусія.
Нік Мейер

28
Насправді tryблоки безкоштовні в будь-якому сучасному компіляторі C, ця інформація датована Ніком. Я також не погоджуюся з тим, що обробляти винятки вищого рівня, оскільки ви втрачаєте інформацію про місцевість (фактичне місце, де інструкція не виконана).
Сліпий

31
@Blindly: верхній обробник винятків не є, щоб обробляти виняток, а насправді кричати вголос, що був необроблений виняток, дати його повідомлення та закінчити програму витончено (поверніть 1 замість дзвінка до terminate) . Це більше механізм безпеки. Крім того, try/catchє більш-менш безкоштовними, коли не існує жодного винятку. Коли є один розповсюджувач, він витрачає час кожен раз, коли його кидають і ловлять, тож ланцюг try/catchцього лише повторного викидання не є витратним.
Матьє М.

17
Я не погоджуюсь, що ви завжди повинні зіткнутись за невдалим винятком. Сучасний дизайн програмного забезпечення дуже відокремлений, тому чому ви повинні карати решту програми (і що ще важливіше - користувача!) Лише за те, що сталася одна помилка? Розбивши абсолютно останнє, що ви хочете зробити, принаймні спробуйте надати користувачеві невелике вікно коду, яке дозволить їм зберегти роботу, навіть якщо не можна отримати доступ до решти програми.
Кендалл Гельмстеттер Гелнер

21
Кендалл: Якщо виняток потрапляє до обробника верхнього рівня, ваша заявка за визначенням знаходиться у невизначеному стані. Хоча в деяких конкретних випадках може бути корисно збереження даних користувача (відновлюється відновлення документів Word), програма не повинна перезаписувати жодних файлів і не призначати базу даних.
Х'ю Брокетт

136

Як заявляли Мітч та інші , ви не повинні виловлювати виняток, який не плануєте якось поводитися з ними. Ви повинні розглянути, як програма збирається систематично обробляти винятки під час її проектування. Зазвичай це призводить до наявності шарів обробки помилок на основі абстракцій - наприклад, ви обробляєте всі помилки, пов’язані з SQL, у коді доступу до даних, щоб частина програми, яка взаємодіє з об’єктами домену, не піддавалася факту, що там є десь під кришкою.

Існує кілька супутніх запахів коду, яких ви, безумовно, хочете уникати, крім запаху "ловити все скрізь"

  1. "catch, log, rethrow" : якщо ви хочете скористатися журналом на основі масштабів , тоді напишіть клас, який випромінює заяву журналу у своєму деструкторі, коли стек розгортається через виняток (ala std::uncaught_exception()). Все , що вам потрібно зробити , це оголосити екземпляр протоколювання в рамках , які ви зацікавлені і, вуаля, ви не лісозаготівлі і немає непотрібного try/ catchлогіка.

  2. "зловити, кинути перекладене" : це зазвичай вказує на проблему абстракції. Якщо ви не реалізуєте об'єднане рішення, де ви перекладаєте кілька конкретних винятків у ще один загальний, у вас, ймовірно, є непотрібний шар абстракції ... і не кажіть, що "мені це може знадобитися завтра" .

  3. "ловити, прибирати, повторювати" : це один із моїх вихованців-пів. Якщо ви бачите багато цього, слід застосувати придбання ресурсів - це методи ініціалізації та розмістити частину очищення в деструкторі екземпляра об’єкта двірника .

Я вважаю, що код, засмічений try/ catchблоками, є хорошою ціллю для перегляду та рефакторингу коду. Це вказує на те, що або обробка винятків недостатньо зрозуміла, або код перетворився на ам-бабу і вкрай потребує рефакторингу.


6
№1 для мене нове. +1 для цього. Крім того, я хотів би відзначити загальний виняток №2, який полягає в тому, що якщо ви часто проектуєте бібліотеку, вам потрібно перекласти внутрішні винятки в щось, що вказане в інтерфейсі вашої бібліотеки, щоб зменшити зв'язок (це може бути, що ви маєте на увазі "федеративним рішенням", але я не знайомий з цим терміном).
rmeador

3
В основному, що ви сказали: parashift.com/c++-faq-lite/exceptions.html#faq-17.13
Björn Pollex,

1
№2, де це не запах коду, але має сенс, можна покращити, зберігаючи старий виняток як вкладений.
Дедуплікатор

1
Щодо №1: std :: uncaught_exception () повідомляє вам, що в рейсі є виняткове виняток, але лише пункт AFAIK дозволяє визначити, що таке виключення насправді. Отже, хоча ви можете зафіксувати той факт, що ви виходите зі сфери через невиконаний виняток, лише додається спробу / ловіння, що додається, дозволяє реєструвати будь-які дані. Правильно?
Джеремі

@Jeremy - ти прав. Я зазвичай реєструю дані про винятки, коли обробляю виняток. Відстежувати втручаються кадри дуже корисно. Зазвичай вам потрібно записати ідентифікатор потоку або якийсь ідентифікаційний контекст, а також співвіднести рядки журналу. Я використовував Loggerклас, аналогічний log4j.Loggerтакому, що включає ідентифікатор потоку в кожному рядку журналу і видав попередження в деструкторі, коли виняток був активним.
Д.Шоулі

48

Тому що наступне питання - "Я зловив виняток, що робити далі?" Що ти робитимеш? Якщо ви нічого не робите - це приховування помилок, і програма могла "просто не працювати" без жодного шансу знайти те, що сталося. Вам потрібно зрозуміти, що саме ви будете робити, як тільки ви спіймали виняток, і лише спіймаєте, якщо знаєте.


29

Вам не потрібно покривати кожен блок пробними перехопленнями, оскільки спроба улову може все-таки вибирати необроблені винятки, кинуті в функції, що рухаються далі в стек викликів. Отже, замість того, щоб кожна функція мала спроб, ви можете мати її на логіці верхнього рівня програми. Наприклад, може бути SaveDocument()рутина верхнього рівня, який вимагає багато методів , які вимагають інших методів і т.д. Ці суб-методам не потрібні власні Try-улови, тому що якщо вони кидають, це все-таки спіймано SaveDocument()зловити «s.

Це добре з трьох причин: це зручно, тому що у вас є одне місце, щоб повідомити про помилку: SaveDocument()блок (и) лову. Не потрібно повторювати це протягом усіх підметодів, і все одно ви хочете: одне єдине місце, щоб дати користувачеві корисну діагностику про те, що пішло не так.

По-друге, збереження скасовується щоразу, коли викидається виняток. З кожним піддослідним методом випробування, якщо викид виняток, ви потрапляєте у блок вловлювання цього методу, виконання залишає функцію, і вона продовжується наскрізь SaveDocument(). Якщо щось вже пішло не так, ви, швидше за все, захочете зупинитися саме там.

По-третє, всі ваші під-методи можуть припускати, що кожен дзвінок є успішним . Якщо виклик не вдався, виконання перейде до блоку спіймання, і наступний код ніколи не виконується. Це може зробити ваш код набагато чистішим. Наприклад, ось з кодами помилок:

int ret = SaveFirstSection();

if (ret == FAILED)
{
    /* some diagnostic */
    return;
}

ret = SaveSecondSection();

if (ret == FAILED)
{
    /* some diagnostic */
    return;
}

ret = SaveThirdSection();

if (ret == FAILED)
{
    /* some diagnostic */
    return;
}

Ось як це можна записати за винятками:

// these throw if failed, caught in SaveDocument's catch
SaveFirstSection();
SaveSecondSection();
SaveThirdSection();

Зараз набагато зрозуміліше, що відбувається.

Зауважте, що безпечний код виключення може бути складнішим для запису іншими способами: ви не хочете просочувати жодну пам'ять, якщо викинутий виняток. Переконайтеся, що ви знаєте про контейнери RAII , STL, смарт-покажчики та інші об’єкти, які звільняють свої ресурси в деструкторах, оскільки об'єкти завжди руйнуються перед винятками.


2
Чудові приклади. Так, ловіть якомога вище в логічних одиницях, наприклад, навколо деяких "транзакційних" операцій, таких як завантаження / збереження / тощо. Ніщо не виглядає гірше, ніж код, переповнений повторюваними, надлишковими try- catchблоками, які намагаються позначити кожну дещо іншу перестановку якоїсь помилки з дещо іншим повідомленням, коли насправді всі вони повинні закінчуватися однаково: транзакції або збоєм програми та виходом! Якщо трапляється помилка, яка заслуговує на виняток, я вважаю, що більшість користувачів просто хочуть врятувати те, що вони можуть, або, принаймні, залишити в спокої, не маючи справу з 10 рівнями повідомлень про це.
підкреслюй_d

Просто хотів сказати, що це одне з найкращих пояснень, які я коли-небудь читав: "кидай рано, лови пізно": стислі та приклади ідеально ілюструють твої моменти. Дякую!
corderazo00

27

Герб Саттер писав про цю проблему тут . Напевно варто прочитати.
Тизер:

"Писання безпечного для винятку коду полягає в принципі написання" спробувати "і" зловити "в потрібних місцях." Обговоріть.

Відверто кажучи, ця заява відображає принципове непорозуміння безпеки виключень. Винятки - це ще одна форма повідомлення про помилки, і ми, звичайно, знаємо, що написання безпечного для помилок коду - це не лише те, де перевіряти коди повернення та обробляти умови помилок.

Власне, виявляється, що безпека виключень рідко стосується написання "спробувати" та "зловити" - і чим рідше, тим краще. Крім того, ніколи не забувайте, що безпека виключень впливає на частину дизайну коду; це ніколи не є просто задумливим, яке може бути дооснащене кількома додатковими висловлюваннями про вилов, як якщо б це було приправою.


15

Як зазначено в інших відповідях, ви маєте назвати виняток лише у тому випадку, якщо зможете зробити якусь розумну обробку помилок для цього.

Наприклад, у запитанні, яке породило ваше запитання, запитуючий запитує, чи безпечно ігнорувати винятки для lexical_castцілого числа до рядка. Такий акторський склад ніколи не повинен провалюватися. Якщо це не вдалося, у програмі щось пішло жахливо. Що ви могли зробити, щоб відновитись у цій ситуації? Напевно, найкраще просто відпустити програму, оскільки вона знаходиться в стані, якому не можна довіряти. Тож обробка винятку може бути найбезпечнішою справою.


12

Якщо ви завжди одразу обробляєте винятки у виклику методу, який може кинути виняток, винятки стають марними, і вам краще використовувати коди помилок.

Вся суть винятків полягає в тому, що їх не потрібно обробляти в кожному методі в ланцюзі викликів.


9

Найкраща порада, яку я чув, полягає в тому, що вам слід коли-небудь ловити винятки лише в тих місцях, де ви можете розумно зробити щось про винятковий стан, і що "ловити, записувати та звільняти" не є хорошою стратегією (якщо іноді неминуче в бібліотеках).


2
@KeithB: Я вважаю це другою найкращою стратегією. Краще, якщо ви зможете записати журнал іншим способом.
Девід Торнлі

1
@KeithB: Це стратегія "краще, ніж нічого в бібліотеці". "Ловіть, записуйте, справляйтеся з цим належним чином" краще, де це можливо. (Так, я знаю, що це не завжди можливо.)
стипендіати

6

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

Деякі з існуючих відповідей виглядають як "Вам не потрібно обробляти виняток. Хтось інший зробить це в стеці". На мій досвід, це поганий привід не думати про обробку винятків у розробленому в даний час фрагменті коду, що робить виняток для вирішення проблеми когось іншого чи пізніше.

Ця проблема різко зростає в розподіленій розробці, де вам може знадобитися викликати метод, реалізований співробітником. І тоді вам доведеться оглянути вкладений ланцюжок викликів методів, щоб з’ясувати, чому він / вона кидає на вас якийсь виняток, з яким можна було б обробитись набагато простіше при найглибшому вкладеному методі.


5

Порада, яку мені дав колись професор комп'ютерних наук, була такою: "Використовуйте блоки" Спробуйте і ловіть "лише тоді, коли не вдається впоратися з помилкою за допомогою стандартних засобів".

Як приклад, він сказав нам, що якщо програма стикається з якоюсь серйозною проблемою в місці, де неможливо зробити щось на кшталт:

int f()
{
    // Do stuff

    if (condition == false)
        return -1;
    return 0;
}

int condition = f();

if (f != 0)
{
    // handle error
}

Тоді вам слід використовувати спробувати, ловити блоки. Хоча ви можете використовувати винятки, щоб впоратися з цим, це, як правило, не рекомендується, оскільки винятки є дорогими.


7
Це одна стратегія, але багато людей рекомендують ніколи не повертати коди помилок або статуси відмов / успіху з функцій, використовуючи натомість винятки. Поводження з помилками на основі винятку часто простіше читати, ніж код на основі помилок. (Для прикладу див. Відповідь AshleysBrain на це запитання.) Також завжди пам’ятайте, що багато професорів інформатики мають дуже малий досвід написання реального коду.
Крістофер Джонсон

1
-1 @Sagelika Ваша відповідь полягає у тому, щоб уникнути винятку, тому не потрібно намагатися застати.
Vicente Botet Escriba

3
@Kristopher: Інші великі недоліки повернення коду - це те, що реально легко забути перевірити код повернення, і відразу після дзвінка це не обов'язково найкраще місце для вирішення проблеми.
Девід Торнлі

Так, це залежить, але в багатьох випадках (відміняючи людей, які кидають, коли вони справді не повинні), винятки є кращими для повернення кодів з стількох причин. в більшості випадків ідея про те, що винятки згубні для виконання, є великою думкою "[цитата потрібна]
підкреслюється

3

Якщо ви хочете перевірити результат кожної функції, використовуйте коди повернення.

Мета винятку полягає в тому, щоб ви могли менше перевіряти результати. Ідея полягає в тому, щоб виокремити виняткові (незвичні, рідкісніші) умови від вашого звичайнішого коду. Це забезпечує звичайний код більш чистим та простим - але все-таки здатний впоратися з тими винятковими умовами.

У добре розробленому коді більш глибокі функції можуть кидатись, а вищі функції можуть потрапляти. Але головне в тому, що багато функцій "між ними" взагалі будуть звільнені від тягаря поводження з винятковими умовами. Вони мають бути лише "безпечними для винятку", а це не означає, що їх треба спіймати.


2

Я хотів би додати до цієї дискусії те, що, оскільки C ++ 11 , це має багато сенсу, доки кожен catchблок rethrows - виняток до моменту, коли він може / повинен оброблятися. Таким чином можна створити зворотній слід . Тому я вважаю, що попередні думки частково застаріли.

Використовуйте std::nested_exceptionіstd::throw_with_nested

У StackOverflow описано тут і тут, як цього досягти.

Оскільки ви можете це зробити з будь-яким похідним класом винятків, ви можете додати багато інформації до такого зворотного треку! Ви також можете поглянути на мій MWE на GitHub , де backtrace виглядатиме приблизно так:

Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"

2

Мені було надано "можливість" врятувати кілька проектів, і керівники замінили всю команду розробників, оскільки у додатку було занадто багато помилок, і користувачі втомилися від проблем і обходу. Усі ці кодові бази мали централізоване поводження з помилками на рівні програми, як описано вгорі голосованої відповіді. Якщо ця відповідь є найкращою практикою, чому вона не працювала і не дозволяла попередній команді розробників вирішувати проблеми? Можливо, іноді це не працює? У відповідях вище не згадується, скільки часу розробники витрачають на виправлення окремих проблем. Якщо час для вирішення проблем є ключовою метрикою, то інструментальний код із блоками try..catch є кращою практикою.

Як моя команда усунула проблеми, не змінивши інтерфейсу користувача? Простий, кожен метод оснащений try..catch заблоковано, і все реєструвалось у місці відмови разом із назвою методу, значеннями параметрів методу, об'єднаними в рядок, що передається разом із повідомленням про помилку, повідомлення про помилку, ім'я програми, дату, та версія. За допомогою цієї інформації розробники можуть запустити аналітику щодо помилок, щоб виявити виняток, який трапляється найбільше! Або простір імен з найбільшою кількістю помилок. Він також може підтвердити, що помилка, яка виникає в модулі, належним чином обробляється і не викликається кількома причинами.

Ще однією перевагою цього є те, що розробники можуть встановити одну точку розриву в методі реєстрації помилок, і з однією точкою розриву та одним натисканням кнопки налагодження «вийти» вони перебувають у методі, який не вдався з повним доступом до фактичного об'єкти в місці відмови, зручно доступні в безпосередньому вікні. Це дозволяє дуже легко налагоджувати і дозволяє перетягувати виконання назад до початку методу для дублювання проблеми, щоб знайти точну лінію. Чи дозволяє централізоване управління винятками розробнику копіювати виняток за 30 секунд? Ні.

Заява "Метод повинен виловлювати виключення лише тоді, коли він може впоратися з ним якось розумним чином". Це означає, що розробники можуть передбачити або зустріти кожну помилку, яка може статися до випуску. Якби це правда вищого рівня, обробник винятків додатків не знадобився б і не було б ринку для еластичного пошуку та реєстрації даних.

Такий підхід також дозволяє розробникам знаходити та виправляти періодичні проблеми у виробництві! Чи хотіли б ви налагоджувати без налагодження у виробництві? Або ви віддаєте перевагу телефонувати та отримувати електронні листи від засмучених користувачів? Це дозволяє виправляти проблеми до того, як хтось інший знає, і без необхідності надсилати електронну пошту, чат чи Slack за допомогою підтримки, оскільки все, що потрібно для виправлення проблеми, є саме там. 95% питань ніколи не потрібно відтворювати.

Для належної роботи його потрібно поєднувати з централізованим журналом, який може захоплювати простір імен / модуль, назву класу, метод, входи та повідомлення про помилку та зберігати в базі даних, щоб можна було агрегувати, щоб виділити, який метод не вдається найбільше, щоб він міг бути виправлено першим.

Іноді розробники вирішують викидати винятки до стека з блоку лову, але такий підхід у 100 разів повільніше, ніж звичайний код, який не кидає. Переважний вилов і випуск із веденням журналу.

Ця методика була використана для швидкої стабілізації програми, яка виходила з ладу щогодини для більшості користувачів у компанії Fortune 500, розробленій 12 розробниками протягом 2 років. За допомогою цього 3000 різних винятків було визначено, виправлено, протестовано та розгорнуто за 4 місяці. Це в середньому виправляється кожні 15 хвилин в середньому протягом 4 місяців.

Я погоджуюся, що не цікаво вводити все необхідне для інструментації коду, і я вважаю за краще не дивитися на повторюваний код, але додавати 4 рядки коду до кожного методу варто в перспективі.


1
Перегортання кожного блоку здається непосильним. Це швидко робить ваш код роздутим і болючим для читання. Реєструвати стеження за винятком на вищих рівнях, ви показуєте, де сталася проблема, і що в поєднанні з самою помилкою, як правило, є достатньою інформацією для продовження. Мені було б цікаво, де ви виявили, що це недостатньо. Просто так я можу отримати чужий досвід.
user441521

1
"Винятки в 100 - 1000 разів повільніше, ніж звичайний код, і ніколи не повинні їх повторювати" - це твердження не відповідає дійсності більшості сучасних компіляторів та апаратних засобів.
Мітч Пшеничний

Це здається надмірним і вимагає трохи вводити текст, але це єдиний спосіб провести аналітику за винятками, щоб знайти та виправити найбільші помилки спочатку, включаючи періодичні помилки у виробництві. Блок лову обробляє конкретні помилки, якщо це потрібно, і містить один рядок коду, який записує в журнал.
user2502917

Ні, винятки дуже повільні. Альтернатива - це коди повернення, об'єкти чи змінні. Дивіться це переповнення стека пост ... «Виняток становить , по крайней мере 30000 разів повільніше , ніж коди повернення» stackoverflow.com/questions/891217 / ...
user2502917

1

Окрім наведених вище порад, особисто я використовую деякий спробу + улов + кидок; з наступної причини:

  1. На кордоні різних кодерів я використовую спробу + catch + кидання в коді, написаному власноруч, перш ніж виняток буде передано абоненту, який написано іншими, це дає мені можливість дізнатися про стан помилок, що виник у моєму коді, і це місце набагато ближче до коду, який спочатку викидає виняток, чим ближче, тим простіше знайти причину.
  2. На межі модулів, хоча різний модуль може бути написаний моєю тією ж особою.
  3. Мета Learning + Debug: у цьому випадку я використовую catch (...) у C ++ та catch (Exception ex) у C #, для C ++ стандартна бібліотека не викидає занадто багато винятків, тому цей випадок рідкісний у C ++. Але загальне місце в C #, C # має величезну бібліотеку та зрілу ієрархію винятків, код C # бібліотеки кидає тони винятків, теоретично я (і ви) повинні знати всі винятки з функції, яку ви викликали, і знати причину / випадок, чому ці винятки кидають і вміють граціозно поводитися з ними (пройти мимо або зловити та обробити це на місці). На жаль, насправді дуже важко знати все про потенційні винятки, перш ніж написати один рядок коду. Тож я зафіксую все і нехай мій код говорить вголос, увійшовши (у середовищі продукту) / діалоговому вікні затвердження (у середовищі розробки), коли будь-який виняток дійсно має місце. Таким чином я поступово додаю код обробки винятків. Я знаю, що це конфлікт з добрими порадами, але насправді це працює для мене, і я не знаю кращого способу для цієї проблеми.

1

Я змушений додати ще одну відповідь, хоча відповідь Майка Пшеничного досить добре підсумовує основні моменти. Я думаю про це так. Коли у вас є методи, які роблять кілька речей, ви збільшуєте складність, не додаючи їх.

Іншими словами, метод, який охоплюється спробу лову, має два можливі результати. Ви маєте результат не виключення та результат виключення. Якщо ви маєте справу з безліччю методів, це експоненціально вибухає поза розумінням.

Експоненціально, тому що якщо кожен метод розгалужується двома різними способами, то кожного разу, коли ви викликаєте інший метод, ви підбираєте попереднє число потенційних результатів. На той момент, коли ви назвали п'ять методів, ви максимум до 256 можливих результатів. Порівняйте це з не робити спроб / улов у кожному окремому методі, і у вас є лише один шлях, який слід пройти.

Це в основному, як я на це дивлюся. Ви можете спокуситись стверджувати, що будь-який тип розгалуження робить те саме, але спроба / лови - це особливий випадок, оскільки стан програми в основному стає невизначеним.

Отже, коротше кажучи, спроба / ловить зробити код набагато складнішим для розуміння.


-2

Вам не потрібно приховувати кожну частину коду всередині try-catch. Основне використання try-catchблоку - обробка помилок та отримання помилок / винятків у вашій програмі. Деяке використання try-catch-

  1. Ви можете використовувати цей блок там, де потрібно обробити виняток, або просто можете сказати, що блок написаного коду може кинути виняток.
  2. Якщо ви хочете розмістити свої об'єкти відразу після їх використання, ви можете використовувати try-catchблок.

1
"Якщо ви хочете розпоряджатися вашими об'єктами відразу після їх використання, ви можете використовувати блок" try-catch "." Ви мали намір це сприяти RAII / мінімальному терміну експлуатації об'єкта? Якщо так, то try/ / catchповністю відокремлений / ортогональний від цього. Якщо ви хочете розпоряджатися об'єктами в меншому обсязі, ви можете просто відкрити новий { Block likeThis; /* <- that object is destroyed here -> */ }- не потрібно загортати це в try/, catchякщо, звичайно, вам catchнічого не потрібно , звичайно.
підкреслюй_d

# 2 - Розпорядження об'єктів (створених вручну) за винятком здається мені дивним, це може бути корисним для деяких мов, без сумніву, але, як правило, ви робите це в спробі / нарешті "в межах спробувати / крім блоку", а не зокрема в самому блоці, окрім блоку - оскільки сам об'єкт, можливо, був причиною винятку в першу чергу, і, таким чином, спричинив ще одне виключення і, можливо, збій.
TS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.