Russian Qt Forum
Апрель 27, 2024, 20:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Где взять информацию про имеющиеся классы исключений на Си++?  (Прочитано 6381 раз)
Eten
Гость
« : Март 02, 2011, 16:31 »

Где взять информацию про имеющиеся классы исключений на Си++? Все облазил, знаю что есть класс Exception, и еще несколько классов производных от него. Но в инете, нигде толко найти не могу уже который час.  Плачущий

Я хоть на данный момент и ищу исключение для математических ситуаций, но хотелось бы узнать. Где можно найти всю информацию по Exception и всем производным от него классам исключений в стандартной библиотеке?!

З.Ы.
Не хочу городить огород, когда есть такие классы. Да информации о них нет.  В замешательстве
Записан
meego_man
Гость
« Ответ #1 : Март 02, 2011, 16:37 »

Например здесь, правда на великом и могучем англ Улыбающийся

http://www.cplusplus.com/reference/std/exception/exception/

... Some classes derived from exception are: bad_alloc, bad_cast, bad_exception, bad_typeid, logic_error, runtime_error, ios_base::failure...
Записан
Sancho_s_rancho
Гость
« Ответ #2 : Март 02, 2011, 16:38 »

http://www.aoc.nrao.edu/php/tjuerges/ALMA/STL/html-3.4.6/classstd_1_1exception.html
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #3 : Март 02, 2011, 17:28 »

Если Вы это по поводу математических вычислений, то могу посоветовать использовать библиотеку gsl.
Там уже в самой библиотеке предусмотрены возможные ошибки при вычислениях.
К тому же это очень полная библиотека с хорошей документацией + свободная.

http://www.gnu.org/software/gsl/
« Последнее редактирование: Март 02, 2011, 17:41 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Eten
Гость
« Ответ #4 : Март 02, 2011, 20:21 »

Интересно, а правильно ли я понял, что для математических особых ситуаций мне потребуется самому создавать классы, если не пользоваться сторонними библиотеками (например для ситуации деления на ноль)?
Записан
Fat-Zer
Гость
« Ответ #5 : Март 02, 2011, 20:41 »

Целочисленное деление на ноль - в принципе не возможно перехватиить средствами Си(поправьте меня). Операции с плавающей точкой - вообще не считаются ошибкой, т.е. переменной присваивается NAN или INF и всё. Так что ИМХО, если нужен какой-то особый контроль, то придётся писать свои классы.

ЗЫ: тут в соседней ветке (про преобразование интов и флоатов) нечто подобное обсуждается.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #6 : Март 02, 2011, 21:04 »

Интересно, а правильно ли я понял, что для математических особых ситуаций мне потребуется самому создавать классы, если не пользоваться сторонними библиотеками (например для ситуации деления на ноль)?
Боюсь вам придётся переписывать все функции в которых потенциально возможно появление неприятностей.
Мне вообще, исключения не очень симпатичны.. Я их не использую, к тому же сейчас есть механизм сигнал-слот, который более изящно справляется с этим всем.

ЗЫ: тут в соседней ветке (про преобразование интов и флоатов) нечто подобное обсуждается.
Смеющийся Собственно, как я понял это и есть логическое продолжение той ветки)) Автор тот же))
« Последнее редактирование: Март 02, 2011, 21:06 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Март 03, 2011, 03:43 »

Боюсь вам придётся переписывать все функции в которых потенциально возможно появление неприятностей.
Да чего там бояться - склепать класс exception за 15 минут?

Мне вообще, исключения не очень симпатичны.. Я их не использую, к тому же сейчас есть механизм сигнал-слот, который более изящно справляется с этим всем.
Хорошее словцо "изящно", но по-моему исключения и сигналы никак не альтернатива друг другу. Не видно даже такого примера когда вместо exception можно сигналить или наоборот.
Записан
Eten
Гость
« Ответ #8 : Март 03, 2011, 05:03 »

Боюсь вам придётся переписывать все функции в которых потенциально возможно появление неприятностей.
Да чего там бояться - склепать класс exception за 15 минут?
Очень даже возможно, но меня смущает один момент. Когда задаешь интерфейс, то throw() в скобках через запятую нужно перечислить ситуации, которая он вызывает, т.к. функция по умолчанию может выдать любую особую ситуацию. Дык, вот вопрос. А как корректно и правильно, что не сесть в лужу написать класс особой ситуации деления на ноль? Я то могу и просто пустой класс сделать, а как лучше?

Интересно, а действительно ли в Си++ нет стандартного иерархического набора особых ситуаций, как например в С#, кроме тех что были приведены (от того самого exception-а)?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #9 : Март 03, 2011, 12:52 »

Мне вообще, исключения не очень симпатичны.. Я их не использую, к тому же сейчас есть механизм сигнал-слот, который более изящно справляется с этим всем.
Хорошее словцо "изящно", но по-моему исключения и сигналы никак не альтернатива друг другу. Не видно даже такого примера когда вместо exception можно сигналить или наоборот.
[/quote]
Ну вот смотрите:
На примере деления на ноль.
1) У нас есть класс SomeClass, который реализует всякие там мат. вычисления.. Ниже код с пояснениями самой идеи. (использовал libssc)
Код
C++ (Qt)
#include <iostream>
#include <string>
#include "signal_slot.h"
#include "messenger.h"
 
using namespace std;
 
 
typedef ssc::messenger3<string, string, double&> exception_type; // Это класс, который содержит информацию о том что произошло и где это произошло.. ну и т.д.  
 
/* Вот этот класс и для простоты он имеет только одну функцию */
class SomeClass
{
public:
   ssc::signal<const exception_type &> exception; // сигнал - замещает исключения
 
   double func(double x) {
       if (x == 0.0) // пытаемся делить на ноль!
           exception(exception_type("func", "divizion by zero", x)); /* Шлём сигнал об этом безобразии, указывая также имя функции, где это произошло, что произошло, и ссылку на x*/
       return 1.0 / x;
   }
};
 
/* Класс обработчик исключений */
class ExceptionHandler : public ssc::trackable
{
public:
   void handleEvent(const exception_type& e) { /* Выводит информацию о том что случилось и */
       cout << e.arg1 << endl;
       cout << e.arg2 << endl;
       cout << e.arg3 << endl;
       const double epsilon = 0.0000001;
       e.arg3 = epsilon; // Вмешивается в дальнейший процесс, изменяя наш x!
   }
};
 
 
int main()
{
  SomeClass sc; // создаём наш класс
  ExceptionHandler eh; // создаём класс обработчик
 
  sc.exception.connect(&eh, &ExceptionHandler::handleEvent); // коннектим их
 
  double res = sc.func(0.0); // Вызываем функцию в нуле!
 
  cout << res << endl; // и что же получаем??
 
   return 0;
}
 

Ну вот приммерно так..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Март 03, 2011, 13:25 »

Код
C++ (Qt)
   double func(double x) {
       if (x == 0.0) // пытаемся делить на ноль!
           exception(exception_type("func", "divizion by zero", x)); /* Шлём сигнал об этом безобразии, указывая также имя функции, где это произошло, что произошло, и ссылку на x*/
       return 1.0 / x;
   }
 
Ну это сильно проигрывает обычному exception

- код не прерывается, надо вставлять return, если ф-ция глубоко вложена - то везде по стеку

- напр. человек разрабатывает класс пока не заботясь как он будет использоваться. Но он уже должен иметь ввиду некую систему, полагать что в дальнейшем (каждый) пользователь класса свяжет "слот-сигнал веники" до того. А тот пользователь в еще более неловком положении потому что Вы заставляете его изучать Вашу систему  Улыбающийся Если напиcано throw - сразу ясно, а кто такой exception_type? Надо разбираться - а зачем?

Не проще ли так
Код
C++ (Qt)
   double func(double x)
  {
       double result  = 1.0 / x;
       if (TestNan(result))
           throw MyException("func", "float divizion by zero", x);
       return result;
   }
 
   int funcInt(int x, int y)
  {
       if (!x)
           throw MyException("funcInt", "integer divizion by zero", x);
       return y / x;
   }
 
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #11 : Март 03, 2011, 14:35 »

Цитировать
Ну это сильно проигрывает обычному exception

- код не прерывается, надо вставлять return, если ф-ция глубоко вложена - то везде по стеку

- напр. человек разрабатывает класс пока не заботясь как он будет использоваться. Но он уже должен иметь ввиду некую систему, полагать что в дальнейшем (каждый) пользователь класса свяжет "слот-сигнал веники" до того. А тот пользователь в еще более неловком положении потому что Вы заставляете его изучать Вашу систему  Улыбающийся Если напиcано throw - сразу ясно, а кто такой exception_type? Надо разбираться - а зачем?
Ну я с Вами тут не соглашусь. И вот почему:
1) Если ошибка настолько ужасна, что продолжать программу дальше нельзя, то стандартные исключения здесь очень кстати. После блока catch всё и закончится..
А вот если есть надежда, что обработчик исключения всёже как то исправит ситуацию, то нужно позаботится о том, чтобы заново повторить тот фрагмент, где было вызвано исключение. И вот здесь начинается самое весёлое. Т.е. после обработки исключения в блоке catch Вам придётся явно! вернуть управление к точке возникновения ошибки.
Как? Помещать блок try в бесконечный цикл? Нет уж, спасибо))

Цитировать
- напр. человек разрабатывает класс пока не заботясь как он будет использоваться. Но он уже должен иметь ввиду некую систему, полагать что в дальнейшем (каждый) пользователь класса свяжет "слот-сигнал веники" до того. А тот пользователь в еще более неловком положении потому что Вы заставляете его изучать Вашу систему
   
А я например могу не заставлять пользователя явно связывать сигнал со слотом. Это можно сделать в конструкторе класса, который занимается расчётами. И вместо класса ExceptionHandler, я могу определить просто функцию:
Код
C++ (Qt)
#include <iostream>
#include <string>
#include "signal_slot.h"
#include "messenger.h"
 
using namespace std;
 
 
typedef ssc::messenger3<string, string, double&> exception_type;
 
int funcF(double x, double y) {  // Пример функции, кидающей обычное исключение
   if (x == 0.0)
       throw exception_type("funcF", "divizion by zero", x);
   return y / x;
}
 
void exceptionHandler(const exception_type &e) { // Функция обработки исключений
   cout << e.arg1 << endl;
   cout << e.arg2 << endl;
   cout << e.arg3 << endl;
   const double epsilon = 0.0000001;
   e.arg3 = epsilon;
}
 
class SomeClass
{
public:
   SomeClass() { // В самом конструкторе соединяем наши сигналы с обработчиками
       exception.connect(exceptionHandler);
   }
   ssc::signal<const exception_type &> exception;
   double func(double x) {
       if (x == 0.0)
           exception(exception_type("func", "divizion by zero", x));
       return 1.0 / x;
   }
};
 
 
int main()
{
  SomeClass sc; // Создаём наш клас и всё..
 
  double res = sc.func(0.0); /* Проблемный момент, но мы хотим
                                                исправить ситуацию не прерывая программу! */

 
  cout << "res = " << res << endl; // До этой точки мы дойдём!
 
  try {
 
      double res = funcF(0.0, 1.0); // А вот функция, кидающая обычные исключения
      cout << "res = " << res << endl; // Сюда мы уже не попадём!! (без лишниз телодвижений)
 
  } catch (exception_type e) {
       cout << e.arg1 << endl;
       cout << e.arg2 << endl;
       cout << e.arg3 << endl;
       const double epsilon = 0.0000001;
       e.arg3 = epsilon; // Вот на этом всё и закончится)
  }
 
   return 0;
}
 
Поэтому это ещё спорный вопрос, что удобней))
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Март 03, 2011, 15:57 »

1) Если ошибка настолько ужасна, что продолжать программу дальше нельзя, то стандартные исключения здесь очень кстати. После блока catch всё и закончится..
Ну почему "все"? Напр. пользователь пытается открыть поврежденный файл данных - конечно отлуп ему, но ведь завершать всю программу необязательно  Улыбающийся

А вот если есть надежда, что обработчик исключения всёже как то исправит ситуацию, то нужно позаботится о том, чтобы заново повторить тот фрагмент, где было вызвано исключение. И вот здесь начинается самое весёлое. Т.е. после обработки исключения в блоке catch Вам придётся явно! вернуть управление к точке возникновения ошибки.
Как? Помещать блок try в бесконечный цикл? Нет уж, спасибо))
Конечно так бывает, но посмотрим на конкретный класс NNumric: разве он знает что делать с ошибкой? Никак не знает, и ненужно/вредно было бы добавлять в него эту ф-циональность. Поэтому он должен выкинуть ошибку наверх, напр тому кто заряжал аргументы, а тот уж пусть разбирается. На мой взгляд здесь классический случай exception.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #13 : Март 03, 2011, 16:08 »

Цитировать
Конечно так бывает, но посмотрим на конкретный класс NNumric: разве он знает что делать с ошибкой? Никак не знает, и ненужно/вредно было бы добавлять в него эту ф-циональность. Поэтому он должен выкинуть ошибку наверх, напр тому кто заряжал аргументы, а тот уж пусть разбирается. На мой взгляд здесь классический случай exception.
Ну я вообще то это всё к тому, что механизм сигнал-слот справляется с такой ситуацией (когда обработчик может исправить ситуацию и вернуть управление) справляется, согласитесь, изящьнее, нежели стандартный сценарий исключений)

К тому же, хочу заметить, что в самой функции (или в классе) exceptionHandler также можно кинуть обычное исключение, например если уж совсем всё плохо) :
Код
C++ (Qt)
void exceptionHandler(const exception_type &e) {
   if (e.arg2 == "Mein Gott!!!")
       throw MyException;
   cout << e.arg1 << endl;
   cout << e.arg2 << endl;
   cout << e.arg3 << endl;
   const double epsilon = 0.0000001;
   e.arg3 = epsilon;
}
 

 Подмигивающий
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.182 секунд. Запросов: 22.