Коли потрібно створювати власний тип виключення?

Я працюю над проектом, де ми реструктуруємо старий C код у новий c ++. А для обробки помилок ми використовуємо винятки. Ми створюємо різні типи виключень для різних модулів. Але я не бачу, що це варто. Але я не маю жодного вагомого аргументу, щоб довести свою думку. Отже, якщо б ми написали стандартну бібліотеку, ви могли б побачити vector_exception, list_excetpion і так далі.

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

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

10
Отримати виняток і створити спеціальні виключення; це добре для налагодження, оскільки допомагає розуміти код. Крім того, вона дає кращу загальну структуру
додано Автор Alberto Miola, джерело
Ідея - мати контроль. Ви ловите винятки, що ваш код піднімається, і ви тільки ловить ті, які ви очікуєте. Це повідомляє користувачам, які читають ваш код, які винятки можуть відбутися тут. Якщо ви подивитеся на певний виняток, він може прийти з будь-якого місця, з вашого коду, з залежностей, хто знає, а не з хлопця, який дивиться на ваш код. Якщо ваші міркування не виконують їх, це "це займає повну хвилину мого часу", а потім переосмислити свої міркування. Чудово вивести їх, не додаючи нічого , будь-якої функціональності чи подібного. Просто виводячи їх, щоб мати можливість їх розрізняти.
додано Автор Aziuth, джерело
Будьте дуже розумними між очікуваними помилками та винятковими помилками. На моєму попередньому проекті, виключення було еквівалентно панічному збереженню та вбивству програми. На іншому проекті, кидаючи виняток би вилка та ядро-звалище та тоді ми зробимо після смерті стек backtrace щоб побачити що поїхав awry. ІМО, виключення кидання не повинні використовуватися для керування потоком.
додано Автор Eljay, джерело
@Aziuth Тоді чому існує логічне поділ помилок у std. І чому тільки один bad_alloc. Чому б не list_bad_alloc, vector_bad_alloc. Це більш описово. Чи не так?
додано Автор Amit Bhaira, джерело

5 Відповіді

Створіть власні типи виключень, коли:

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

Окремі виключення list і vector не представляються вартісними, якщо про них немає чітко окресленого списку або вектора. Ви дійсно збираєтеся мати різну обробку вилову залежно від того, який тип контейнера мав помилку?

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

7
додано

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

Використання спеціального виключення для всіх різних модулів додає декілька переваг:

  • Спеціальне повідомлення для кожного випадку, що робить його більш корисним для звітів
  • _li
  • Під час аварії IDE може показувати тип виключення, що ще більше допомагає відладкою
4
додано

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

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

Нечестивим альянсом буде створення ієрархії виключень:

std::exception
  EXProjectBase
    EXModuleBase
      EXModule1
      EXModule2
    EXClassBase
      EXClassMemory
      EXClassBadArg
      EXClassDisconnect
      EXClassTooSoon
      EXClassTooLate

Потім наполягайте на тому, що кожен фактичний виняток виходить з модуля і класифікації. Потім ви можете зловити будь-який сенс, який має сенс, наприклад, від'єднання, а не окремо захопити HighLevelDisconnect і LowLevelDisconnect.

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

1
додано

Я бачу дві можливі причини.

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

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

1
додано

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

void MyClass::function() nothrow(false) {

   //...
    if (errorCondition) {
        throw std::exception("Error: empty frame");
    }
}
void MyClass::function() nothrow(false) {

   //...
    if (errorCondition) {
        throw EmptyFrame();
    }
}

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

0
додано
Я думаю, ви маєте на увазі noexcept (false) , а не nothrow (false) для специфікатора.
додано Автор Eljay, джерело
IT KPI C/С++ новым годом
IT KPI C/С++ новым годом
747 учасників

Чат обсуждения С/С++. - Вопросы "напишите за меня лабу" - это оффтоп. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/1147