Пользовательский класс исключений — зачем он нам нужен?

#c #exception #exception-handling #custom-exceptions

#c #исключение #пользовательские исключения

Вопрос:

Я читал о пользовательском исключении.. Это то, что я сделал.

 #include <iostream>
#include <exception>
#include <stdexcept>

using namespace std;

class myBase : public exception
{
public:
    myBase() {};
    virtual ~myBase(void) {};
    virtual const char* what() const { return "Hello, you have done a mistake"; }
};

class myDerived : public myBase
{
public:
    myDerived() {};
    virtual ~myDerived(void) {};
    const char* what() const { return "Hello, you have done a mistake in - derived class"; }
};

int main(void)
{
    try
    {
        throw myDerived();
    }
    catch (exceptionamp; e)
    {
        cout << e.what() << endl;
    }

    getchar();
    return 0;
}
  

Я понял это, я могу создавать объекты своего пользовательского класса и могу их перехватывать. Я не понимаю цели этого. Может кто-нибудь объяснить мне, зачем нам нужен пользовательский класс исключений? Любые практические примеры помогут мне понять цель использования пользовательских классов исключений.

Спасибо.

Комментарии:

1. Что, если другой пользователь, определенный class пользователем, наследует (например, class myDerived2 ) от exception и выдает, вы catch не можете различить два исключения.

Ответ №1:

Допустим, существует также другой пользовательский class класс, который также наследует от class myBase :

 class myDerived2 : public myBase {
public:
    myDerived2() {}
    virtual ~myDerived2() {}
};
  

и допустим, у вас есть try catch предложение:

 try {
  myDerived  A;
  myDerived2 B;
  ...
  /* to staff with both A and B */
  ...
} catch (std::exceptionamp; e){
  cout << e.what() << endl; 
}
  
  • В приведенном выше try - catch предложении вы ограничиваете себя, обрабатывая исключения типа myDerived и myDerived2 идентичным образом.

  • Что, если вы хотите обрабатывать броски типа myDerived и myDerived2 по-другому?

  • Тогда вам пришлось бы определить другое try-catch предложение:


 try {
  myDerived  A;
  myDerived2 B;
  ...
  /* to staff with both A and B */
  ...
} catch (myDerived amp;d1) {
  /* treat exception of type myDerived */
} catch (myDerived amp;d2) {
  /* treat exception of type myDerived2 */
}
  
  • Из приведенного выше примера, я думаю, ясно, что определение пользовательских исключений дает программисту ценный и универсальный инструмент для обработки бросков более универсальным и специализированным способом.

Комментарии:

1. Сначала спасибо за ответ. Мой вопрос в том, что я создаю объект своего класса и могу перехватить его в блоке catch. Зачем создавать класс для этого? Есть ли смысл создавать пользовательский класс для исключений? какую мощность я получу, если создам пользовательский класс?

2. Я думаю, из примера ясно, что, создавая пользовательские исключения, у вас есть возможность перехватывать и обрабатывать их отдельно (т. Е. специализированным образом). То есть в вашем случае вы перехватываете все исключения типа std::exception и обрабатываете их одинаково, независимо от того, является ли фактический объект myDerived или какой-либо другой объект, который также наследуется от std::exception .

Ответ №2:

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

в этом игрушечном примере на основе переменной one генерируется другое исключение, которое обрабатывается в операторах catch. В этом случае «строка» печатается в stdout .

 #include <iostream>

using namespace std;

int main(void)
{
    int one = 0;
    try
    {
        if(one)
            throw 1;
        else
            throw "string";
    }
    catch (intamp; i)
    {
        cout << i << endl;
    }
    catch (const char* s)
    {
        cout << s << endl;
    }

    return 0;
}