Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Исключение

436
31 августа 2007 года
Fevzi
87 / / 02.04.2005
как то на собеседовании по C++ задали вопрос:

есть несколько файлов, которые мы хотим открыть и прочитать оттуда,
есть фун-ии, которые открывают файл и читают оттуда, эти фун-ии все разные: то есть есть f1("sdsd.txt"), f2("sas.txt"),f3("fdfdf.txt") и т.д., то есть они открывают и читают по-разному(это так требуется).
Нужно вызвать эти фун-ии в другой фун-ии, т.е:

void MyFun()
{
f1("sdsd.txt");
f2("sas.txt");
f3("fdfdf.txt");
...
}
Файлов в указанном месте может не быть.
Вопрос:как с помощью "исключений" записать фун-ию MyFun() правильно, чтобы каким-то образом оповещать пользователя о несуществующем файле и продолжить выполнение фун-ии MyFun()?
Выдавать сообщение в окно или в cerr не предлагать, т.к. предполагается, что фун-ия MyFun() - из какой-то библиотеки(например:в математической библиотеке, написанной сторонним разработчиком).
276
31 августа 2007 года
Rebbit
1.1K / / 01.08.2005
Я бы передавал функцие параметр калбек-функцию, которая бы вызывалась при отсутствие файла, а реализацию етой функции возложил бы на пользователя библиотеки. Вот только не знаю можно ли вызвать такую калбек-функцию из библиотеки (ламер я покачто).
26K
31 августа 2007 года
Rotveiler
20 / / 29.08.2007
Использовать оператор throw для вызова исключения в коде и блоки try...catch для отловли исключения
276
31 августа 2007 года
Rebbit
1.1K / / 01.08.2005
Цитата: Rotveiler
Использовать оператор throw для вызова исключения в коде и блоки try...catch для отловли исключения


throw остановит выполнение функции. Читай вопрос еще раз.

276
31 августа 2007 года
Rebbit
1.1K / / 01.08.2005
Мдя. Я тоже прочел невнимательно. Надо же с помощю исключений, а я про них ни слова. Но помоему в функции MyFun исключения можно только отлавливать. Если не надо прерифать выполнение, то генерировать исключение - ето неправыльно. (ИМХО)
26K
31 августа 2007 года
Rotveiler
20 / / 29.08.2007
Цитата: Rebbit
throw остановит выполнение функции. Читай вопрос еще раз.



Попробовать создать новый поток, в котором выводить исключения, а функцию продолжать в основном.

3
31 августа 2007 года
Green
4.8K / / 20.01.2000
Исключения тут не помогут, да и использовать исключения в подобных ситуациях - плохая практика.
Rebbit подсказал тебе правильное решение - использовать callback-функцию или другой вид наблюдателя.
260
31 августа 2007 года
Ramon
1.1K / / 16.08.2003
Практика использования исключений при невозможности открыть файл вполне приемлема, не приемлимо открывать файл на каждую операцию и кидать исключения по каждому чиху, исключения кидаются при серьезных ошибках после которых приложение как правило завершается.

Делаетцо примерно так:
Код:
void MyFun()
{
    try
    {
        f1("sdsd.txt");
    }
    catch (exception&)
    {
        cerr << "FATAL ERROR!!!" << endl;
    }

    // Здесь продолжает исполняться MyFun
}


Внутри f1 при невозможности открыть файл должно быть начертано "throw exception()", что вызывает исключение с объектом класса exception, описывающего это исключение.
3
31 августа 2007 года
Green
4.8K / / 20.01.2000
Цитата: Ramon
Практика использования исключений при невозможности открыть файл вполне приемлема, не приемлимо открывать файл на каждую операцию и кидать исключения по каждому чиху, исключения кидаются при серьезных ошибках после которых приложение как правило завершается.



Читаем топик:

Цитата: Fevzi

Вопрос:как с помощью "исключений" записать фун-ию MyFun() правильно, чтобы каким-то образом оповещать пользователя о несуществующем файле и продолжить выполнение фун-ии MyFun()?



Исключения нужны лишь в исключительных/критичных ситуациях.
В данном случае они не нужны.
Поэтому, на собеседовании я бы так и сказал: в данном случае исключение здесь - лишнее.

Более того, если применить исключения так, как показал Ramon (я понимаю, что это всего лишь "простой пример"), то остальная часть программы никогда не узнает о случившимся. А как уже говорилось исключения предназначены для критических ошибок, оказывающих влияние на всю программу.

276
31 августа 2007 года
Rebbit
1.1K / / 01.08.2005
Цитата: Green
исключения предназначены для критических ошибок, оказывающих влияние на всю программу.


Раз уж об етом завели розговор .....
Мне приходилось делать програму которая должна била роботать с минимальным вмешательством человека (админа). Ето был промежуточный уровень (прокладка) между апликейшеном который генерировал документы и сервисом который их принимал, давал подтверждения, оповещал об ошибках в документе и т.п. Собственно прокладка занималась суто транспортом, принимала документ от апликейшена, отправляла сервису, менялась с ним промежуточными сообщениями пока не получала окончательный результат, который отправлялся апликейшену.
Прикращение роботы прокладки изза сбоя был недопустим.
Я старался перехватить все ексепшены которые могли быть визваны обектами которые я юзал, но в то же время я генерировал и свои исключения, которие тоже перехватывал. При возникновении ексепшена я старался както возобновить роботу моей прокладки (ну к примеру еще раз отослать документ) или если возобновление было недопустимым - писал лог-ошибок.

Мой вопрос.
Завершение роботы програмы не происходило, но роботать с ексепшенами мне было довольно удобно. Я плохо спроектировал свою програму или же такое использование ексепшенов вполне приемлимо ?

12K
31 августа 2007 года
__AleXX__
133 / / 02.04.2007
Использование эксепшенов всегда приемлимо, когда обработка определенных ситуаций может происходить на нескольких, на разных уровнях.

Но при работе с исключениями:
1. Замедляется выполнение программы. (много времени тратится на посылку исключения, в отличие от простого перехвата возвращаемых значений функции).
2. Надо иметь в виду что при бросании искльчения все локальные объекты в текущем блоке разрушаются.
3. Плохо бросать искючения в деструкторах (следует искючить возможность бросания исключения в исключении).
3
31 августа 2007 года
Green
4.8K / / 20.01.2000
Цитата: Rebbit

Мой вопрос.
Завершение роботы програмы не происходило, но роботать с ексепшенами мне было довольно удобно. Я плохо спроектировал свою програму или же такое использование ексепшенов вполне приемлимо ?



Сложно сказать.
Все зависит от возможности и эффективности вариантов решения.
Если исключения навязаны сторонними библиотеками, то о чем тут говорить. Если твои исключения хорошо вписывались в схему обработки исключений сторонних библиотек, то смысла разделять обработку на свои/чужие не вижу. Если же тебе пришлось делать несколько схем обработки исключений, то тогда возможно архитектура не совсем верна.

Что я подразумеваю под схемой обработки исключений.
В моем понимании обработка исключений должна происходить как можно выше по иерархии вызовов. Т.е. грубо говоря идеальное место - это функция main. :)
Конечно, это не всегда возможно и не всегда целесообразно. Например (отвлеченный,довольно абстрактный пример, не берите его за основу реализации), мы имеем ряд взаимозаменяемых и взаимодополняемых датчиков. Есть программа управляющая на основе показаний этих датчиков какими-то органами управления. Допустим, что при выходе датчика из строя происходит исключение. Естественно, что обработка этих исключений должна происходить в блоке предоставляющем показания с датчиков, а не в основном или др. блоках программы, т.к. мы условились, что датчики взаимозаменяемы и блок может сам определить, как ему теперь снимать информацию для предоставления основной системе. Т.о. мы имеем как-бы враппер (обертку) над этими исключениями, отделяющую логику работы в исключительных ситуациях от основной системы. Т.е. когда системе нет особого дела (до последнего живого датчика), что там происходит, ей главное информация.

Если же выход датчика из строя оказывает влияние на всю систему, то эту обработку наряду с обработкой выхода из строя остальных критичных узлов системы лучше вынести на уровень всей системы. Т.о. мы имеем общий механизм обработки однотипных (критичных ко всей системе) исключений.
Теперь если ты пристыковываешь свой блок к такой системе, и выход его из строя так же критичен для всей системы, есть смысл завести его в общую схему обработки исключений.

92
31 августа 2007 года
Тень Пса
2.2K / / 19.10.2006
по-моему вообще нужно обрабатывать возможность отсутствия файла в функциях f1, f2, f3, ... или возвращать что-то типа результата FileExists (true, false)... и всё, тогда и остальные смогут узнать, и проблемы вызова в функции или еще где-то не возникнет.

если я не прав, то почему?
276
31 августа 2007 года
Rebbit
1.1K / / 01.08.2005
Цитата: Green
Сложно сказать.
Если же тебе пришлось делать несколько схем обработки исключений, то тогда возможно архитектура не совсем верна.



Роботало у меня примерно так. Структуру мне помагали делать, поскольку сам бы я сделал намного хуже. Обмен шел по нттп. Каждый документ обробатывался в отдельном потоке поскольку сервис их обрабатывал асинхронно. Робота с документом разделялась на несколько стадий: отправка, ожидание ответа (на етой стади я обращался с запросом на ответ, а сервис или давал мне ответ или оповещал через какое время мне обратится к нему еще раз), оброботка ошибок в посланом документе, потверждение получения мною ответа, удаление документа и всей супутствуещей инфы с сервиса. На каждой стадии мной генерировался хмл определенной структуры и парсался ответ сервиса.
В верхнем цикле каждого потока в зависимости от стадии обмена вызывался нужний обэкт которий генерировал, отправлял и парсил хмл.

Исключения у меня были двох типов:
(возможно я плохо подобрал названия для етих типов)

1. Внешние - не соединился с сервисом, превышен интервал ожидания....
В таком случае я делал таймаут и несколько раз пробовал повторить.
Если исключение повторялось несколько раз, обрабатывал так же как и второй тип исключений.

2. Внутренние (те которие я генерировал) - сервис не понял мой хмл или я не понял ответ сервиса.
Документация по стуктуре документов была не идеальной и схем для валидацыи у меня не было. Я использовал етот тип исключений для того чтоб отследить правильно ли я генерю и парсаю документы.
Если происходило такое исключение все данные сохранялись и поток останавливался. Я прекращал выполнение всего, поскольку мне надо было поправить мою програму и начать с того места где я закончил обмен (условно конечно. Я не делал джамп на то место где произошла ошибка, просто оставлял данные нетронутыми).

309
01 сентября 2007 года
el scorpio
1.1K / / 19.09.2006
Как вариант, следующий код:
Код:
void MyFun (list<int> &Numbers, list<string> &Messages)
{
Numbers.clear(); Messages.clear();
for (int i = 1; i <= 3; i++)
{
   try
   {
      switch (i)
      {
      case 1:
         f1("sdsd.txt");
         i++;
      case 2:
         f2("sas.txt");
         i++;
      case 3:
         f3("fdfdf.txt");
         i++;
     } // switch
   }
   catch (exception &error)
   {
       Numbers.push_front (i); // запоминаем номер функции
       Messages.push_front (error.message); // запоминаем текст ошибки
   }
} //for
} // функция

Цепочка функций начинает поочерёдно выполняться внутри блока try.
Когда в одной функции происходит ошибка, её номер и текст запоминаются в списках. После чего управление передаётся в начало цикла (в начало блока try), а переменная цикла позволяет выполнить переход к очередной функции.
355
01 сентября 2007 года
&lt;SCORP&gt;
786 / / 21.10.2006
для данной ситуации пример возможно и относительно подходящий.
но НИКОГДА НЕ ПИШИТЕ TRY\CATCH ВНУТРИ ЦИКЛОВ
исключения это в люом языке программирования самая тормозящая конструкция. поэтому если писать try\catch внутри длинных циклов, то производительность будет резко падать. лучше писать цикл в блоке try\catch
350
02 сентября 2007 года
cheburator
589 / / 01.06.2006
[QUOTE=<SCORP>;209147]НИКОГДА НЕ ПИШИТЕ TRY\CATCH ВНУТРИ ЦИКЛОВ[/QUOTE]
Данной ситуации следует избегать, но иногда она неизбежна.
Пример:
Код:
while (true)
{
  bool connected = true;
  try
  {
    Устанавливаем соединение с сервером БД;
  }
  catch (...)
  {
    connected = false;
  }
  while (!connected)
  {
    Ждем 5 секунд;
    connected = true;
    try
    {
      Устанавливаем соединение с сервером БД;
    }
    catch (...)
    {
      connected = false;
    }
  }
  try
  {
    Работаем с БД, выполняем различные запросы;
  }
  catch (...)
  {
    // Если на сервер пролили кофе, соединение разрывается и происходит исключение при попытке выполнения очередного запроса. Но ничего - мы подождем, пока соединение снова установится и возобновим работу в следующей итерации цикла...
  }
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог