#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;
}