С++. Приклад створення власної ієрархії класів, що обробляють виключні ситуації

Приклад створення власної ієрархії класів, що обробляють виключні ситуації

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


Зміст


1. Текст демонстраційного прикладу для додатку типу Console Application

Приклад демонструє обробку виключних ситуацій:

  • ділення на нуль;
  • від’ємний індекс в масиві.

 

#include <iostream>
#include <string>
using namespace std;

// Створення ієрархії класів, що обробляють виключення

// абстрактний базовий клас, створити об'єкт класу неможливо
class BaseException
{
protected:
  // пояснення до виключення - спільне для усіх похідних класів
  string text;

public:
  // чиста віртуальна функція, що виводить текст виключення
  virtual string what() = 0;
};

// клас, що відповідає арифметичним операціям
class ArithmeticException :public BaseException
{
public:
  // конструктори класу
  // конструктор за замовчуванням
  ArithmeticException()
  {
    text = "Error. Arithmetic Exception.";
  }

  // конструктор з заданим текстом
  ArithmeticException(string _text) { text = _text; }

  // перевизначаємо віртуальну функцію what() - обов'язково
  string what() { return text; }
};

// різновид класу ArithmeticException - ділення на 0,
// оскільки клас є внизу ієрархії і з нього успадкувати нічого вже
// не можна, то оголошення класу містить специфікатор final
class DivideByZero final :public ArithmeticException
{
public:
  // конструктор, який містить текст, що описує виключення
  DivideByZero() :ArithmeticException()
  {
    text = "Divide by zero."; // текст за замовчуванням
  }

  // конструктор, що отримує текст від користувача
  DivideByZero(string _text) :ArithmeticException(_text)
  {
    //text = _text;
  }

  string what()
  {
    return text;
  }
};

// різновид класу BaseException
// від'ємний індекс у масиві
// це також final-клас
class NegativeIndex final :public BaseException
{
public:
  // конструктор отримує аргумент за замовчуванням
  NegativeIndex(string _text = "Error. Negative Index.") { text = _text; }

  // обов'язково потрібно перевизначити функцію what()
  string what() { return text; }
};

// Демонстраційна функція для класу NegativeIndex
void DemoExceptions1()
{
  int a[10];
  int index;

  for (int i = 0; i < 10; i++)
    a[i] = i * i;
  cout << "Input index: " << endl;
  cin >> index;

  // перевірка індексу на від'ємне значення
  if (index < 0)
    throw NegativeIndex(); // згенерувати виключення типу NegativeIndex

  cout << "a[" << index << "] = " << a[index] << endl;
}

// Демонстраційна функція для класу ArithmeticException
void DemoExceptions2()
{
  int a, b, c;
  cout << "a = "; cin >> a;
  cout << "b = "; cin >> b;

  // ділити на 0 заборонено
  if (b == 0)
    throw DivideByZero("Divide by 0.");

  cout << "a / b = " << (double)a / b << endl;
}

void main()
{
  try
  {
    // викликати функцію, яка генерує виключення
    DemoExceptions1(); // перевірка на "Negative Index"
    DemoExceptions2(); // перевірка на "Divide by 0"
    cout << "OK!" << endl;
  }
  catch (NegativeIndex e)
  {
    // обробити виключення
    cout << e.what() << endl;
  }
  catch (DivideByZero e)
  {
    cout << e.what() << endl;
  }
}

 



2. Пояснення до роботи програми. Схема ієрархії класів

У прикладі створюється абстрактний базовий клас BaseException в якому оголошуються:

  • рядок text типу string, що є поясненням до виключної ситуації яке виводиться на екран;
  • чиста віртуальна функція what(), яка призначена для виведення рядка text на екран.

З класу BaseException успадковується клас ArithmeticException, який призначений для обробки арифметичних виключних ситуацій. З класу ArithmeticException успадковується два класи:

  • клас DivideByZero – призначений для обробки виключної ситуації ділення на нуль;
  • клас NegativeIndex – призначений для обробки виключної ситуації від’ємного індексу з масиву.

Загальна схема реалізованих класів зображена на рисунку.

C++. Схема реалізованих класів виключень

 

3. Можливість успадкування від класу exception

У прикладі оголошується власний базовий клас BaseException. Рекомендується власні класи обробки виключних ситуацій успадковувати від класу exception бібліотеки C++. Тобто, більш правильно було б оголосити клас BaseException наступним чином:

// клас BaseException успадкований від класу exception
class BaseException: public exception
{
protected:
  string text; // пояснення до виключення - спільне для усіх похідних класів

public:
  virtual string what() = 0; // чиста віртуальна функція, що виводить текст виключення
};

 


Зв’язані теми