logo

Обробка винятків у C++

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

Отже, використовуючи обробку винятків у C++, ми можемо обробляти винятки, щоб наша програма продовжувала працювати.



рекурсія java

Що таке виняток C++?

Винятком є ​​несподівана проблема, яка виникає під час виконання програми. Наша програма раптово завершується з деякими помилками/проблемами. Виняток виникає під час виконання програми (виконання).

Типи винятків C++

У C++ існує два типи винятків

  1. Синхронний: Винятки, які трапляються, коли щось йде не так через помилку у вхідних даних або коли програма не обладнана для обробки поточного типу даних, з якими вона працює, наприклад, ділення числа на нуль.
  2. Асинхронний : Винятки, які знаходяться поза контролем програми, наприклад, збій диска, переривання клавіатури тощо.

C++ спробуй і впіймай

C++ надає вбудовану функцію обробки винятків. Це можна зробити за допомогою наступних спеціалізованих ключових слів: спробувати, зловити та кинути, кожне з яких має різну мету.



Синтаксис try-catch у C++

  try   {     // Code that might throw an exception          throw   SomeExceptionType('Error message');  }    catch  ( ExceptionName e1 ) {     // catch block catches the exception that is thrown from try block   }>

1. спробуйте на C++

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

2. catch в C++

Інструкція catch представляє блок коду, який виконується, коли певний виняток викидається з блоку try. Код для обробки винятку записаний всередині блоку catch.

3. додати C++

Виняток у C++ можна створити за допомогою ключового слова throw. Коли програма зустрічає оператор throw, вона негайно завершує поточну функцію та починає пошук відповідного блоку catch для обробки викинутого винятку.



Примітка: Кілька операторів catch можна використовувати для перехоплення різних типів винятків, створених блоком try.

Ключові слова try і catch бувають парами: ми використовуємо блок try, щоб перевірити деякий код, і якщо код видає виняток, ми обробимо його в нашому блоці catch.

Навіщо нам Обробка винятків у C++?

Нижче наведено основні переваги обробки винятків перед традиційною обробкою помилок:

  1. Відокремлення коду обробки помилок від звичайного коду : У традиційних кодах обробки помилок завжди існують умови if-else для обробки помилок. Ці умови та код обробки помилок змішуються зі звичайним потоком. Це робить код менш читабельним і зручним для обслуговування. З блоками try/catch код для обробки помилок відокремлюється від звичайного потоку.
  2. Функції/Методи можуть обробляти лише вибрані ними винятки : Функція може генерувати багато винятків, але може вирішити обробляти деякі з них. Інші винятки, які викидаються, але не перехоплюються, можуть бути оброблені абонентом. Якщо абонент вирішує не перехоплювати їх, тоді винятки обробляються абонентом абонента.
    У C++ функція може вказати винятки, які вона створює, використовуючи ключове слово throw. Виклик цієї функції повинен певним чином обробити виняток (або вказавши його знову, або перехопивши).
  3. Групування типів помилок : У C++ і базові типи, і об’єкти можуть бути створені як винятки. Ми можемо створити ієрархію об’єктів винятків, згрупувати винятки в просторах імен або класах і класифікувати їх відповідно до типів.

Приклади обробки винятків у C++

Наступні приклади демонструють, як використовувати блок try-catch для обробки винятків у C++.

Приклад 1

Наведений нижче приклад демонструє виключення викидів у C++.

C++




// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >int> numerator = 10;> >int> denominator = 0;> >int> res;> >// check if denominator is 0 then throw runtime> >// error.> >if> (denominator == 0) {> >throw> runtime_error(> >'Division by zero not allowed!'>);> >}> >// calculate result if no exception occurs> >res = numerator / denominator;> >//[printing result after division> >cout <<>'Result after division: '> << res << endl;> >}> >// catch block to catch the thrown exception> >catch> (>const> exception& e) {> >// print the exception> >cout <<>'Exception '> << e.what() << endl;> >}> >return> 0;> }>

>

>

Вихід

Exception Division by zero not allowed!>

Приклад 2

Нижче наведено простий приклад, який демонструє обробку винятків у C++. Вихідні дані програми пояснюють послідовність виконання блоків try/catch.

CPP




// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> using> namespace> std;> int> main()> {> >int> x = -1;> >// Some code> >cout <<>'Before try '>;> >// try block> >try> {> >cout <<>'Inside try '>;> >if> (x <0) {> >// throwing an exception> >throw> x;> >cout <<>'After throw (Never executed) '>;> >}> >}> >// catch block> >catch> (>int> x) {> >cout <<>'Exception Caught '>;> >}> >cout <<>'After catch (Will be executed) '>;> >return> 0;> }>

>

>

Вихід

Before try Inside try Exception Caught After catch (Will be executed)>

Властивості обробки винятків у C++

Властивість 1

Існує спеціальний блок catch під назвою «catch-all», записаний як catch(…), який можна використовувати для перехоплення всіх типів винятків.

приклад

У наведеній нижче програмі int створюється як виняток, але для int немає блоку catch, тому буде виконано блок catch(…).

CPP




ipconfig для ubuntu

// C++ program to demonstate the use of catch all> // in exception handling.> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >// throw> >throw> 10;> >}> >// catch block> >catch> (>char>* excp) {> >cout <<>'Caught '> << excp;> >}> >// catch all> >catch> (...) {> >cout <<>'Default Exception '>;> >}> >return> 0;> }>

>

>

Вихід

Default Exception>

Властивість 2

Неявне перетворення типів не відбувається для примітивних типів.

приклад

У наступній програмі «a» неявно не перетворюється на int.

CPP




//// C++ program to demonstate property 2: Implicit type> /// conversion doesn't happen for primitive types.> // in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '> << x;> >}> >catch> (...) {> >cout <<>'Default Exception '>;> >}> >return> 0;> }>

>

>

Вихід

Default Exception>

Вихід:

Default Exception>

Властивість 3

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

приклад

У наведеній нижче програмі кидається символ char, але немає блоку catch для перехоплення символу.

CPP




// C++ program to demonstate property 3: If an exception is> // thrown and not caught anywhere, the program terminates> // abnormally in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '>;> >}> >return> 0;> }>

>

>

fizzbuzz java

Вихід

terminate called after throwing an instance of 'char'>

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

Примітка : Виняток похідного класу має бути перехоплено перед винятком базового класу.

Як і Java, бібліотека C++ має a стандартний виняток клас, який є базовим класом для всіх стандартних винятків. Усі об’єкти, створені компонентами стандартної бібліотеки, є похідними від цього класу. Таким чином, усі стандартні винятки можна перехопити шляхом перехоплення цього типу.

Властивість 4

На відміну від Java, у C++ усі винятки не перевіряються, тобто компілятор не перевіряє, чи перехоплено виключення чи ні (див. це для деталей). Отже, немає необхідності вказувати всі неперехоплені винятки в оголошенні функції. Однак обробка винятків є рекомендованою практикою.

приклад

Наступна програма компілюється добре, але в ідеалі сигнатура fun() має перелічувати неперевірені винятки.

CPP




// C++ program to demonstate property 4 in exception> // handling.> #include> using> namespace> std;> // This function signature is fine by the compiler, but not> // recommended. Ideally, the function should specify all> // uncaught exceptions and function signature should be> // 'void fun(int *ptr, int x) throw (int *, int)'> void> fun(>int>* ptr,>int> x)> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }>

>

налаштування веб-браузера

>

Вихід

Caught exception from fun()>

Кращий спосіб написати наведений вище код:

CPP




// C++ program to demonstate property 4 in better way> #include> using> namespace> std;> // Here we specify the exceptions that this function> // throws.> void> fun(>int>* ptr,>int> x)>throw>(> >int>*,>int>)>// Dynamic Exception specification> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }>

>

>

Вихід

Caught exception from fun()>

Примітка : використання специфікації динамічних винятків застаріло з C++11. Однією з причин цього може бути те, що він може випадковим чином перервати вашу програму. Це може статися, коли ви створюєте виняток іншого типу, який не згадується в специфікації динамічного винятку. Ваша програма припинить роботу сама, оскільки в цьому сценарії вона викликає (опосередковано) terminate(), який за замовчуванням викликає abort().

Властивість 5

У C++ блоки try/catch можуть бути вкладеними. Крім того, виняток можна повторно створити за допомогою throw; .

приклад

Наступна програма показує вкладеність блоків try/catch.

CPP




// C++ program to demonstrate try/catch blocks can be nested> // in C++> #include> using> namespace> std;> int> main()> {> >// nesting of try/catch> >try> {> >try> {> >throw> 20;> >}> >catch> (>int> n) {> >cout <<>'Handle Partially '>;> >throw>;>// Re-throwing an exception> >}> >}> >catch> (>int> n) {> >cout <<>'Handle remaining '>;> >}> >return> 0;> }>

>

>

Вихід

Handle Partially Handle remaining>

Функція також може повторно викинути функцію, використовуючи той самий викид; синтаксис. Функція може обробити частину та попросити абонента обробити решту.

Властивість 6

Коли виникає виняток, усі об’єкти, створені всередині охоплюючого блоку try, знищуються до того, як керування буде передано блоку catch.

приклад

Наступна програма демонструє вищевказану властивість.

CPP




c програми

// C++ program to demonstrate> #include> using> namespace> std;> // Define a class named Test> class> Test {> public>:> >// Constructor of Test> >Test() { cout <<>'Constructor of Test '> << endl; }> >// Destructor of Test> >~Test() { cout <<>'Destructor of Test '> << endl; }> };> int> main()> {> >try> {> >// Create an object of class Test> >Test t1;> >// Throw an integer exception with value 10> >throw> 10;> >}> >catch> (>int> i) {> >// Catch and handle the integer exception> >cout <<>'Caught '> << i << endl;> >}> }>

>

>

Вихід

Constructor of Test Destructor of Test Caught 10>

Обмеження обробки винятків у C++

Обробка винятків у C++ також має кілька обмежень:

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

Висновок

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

Схожі статті:

  • Найпопулярніші питання та відповіді на співбесіді з обробки винятків C++
  • Тест про обробку винятків у C++