Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Финализация вызовов при обработке исключений 
:(
    Опции темы
regis
Дата 4.2.2008, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 12.12.2005
Где: Москва, Россия

Репутация: 2
Всего: 7



Собственно, возник такой вопрос.
Предположим, что глубоко в последовательности вызовов может быть возбуждено исключение (см. пример):

Код


void inner () {
// ...
throw Exception (...);
}    // inner

void work_func () {
// ...
inner ();
// ...
}    // work_func

void outer () {

try {
    // ...
    work_func ();
    // ...
    } catch (Exception excpt) {
        // обработка excpt здесь...
    };

}    // outer



Вопрос в том, как обработать ненормальное завершение работы work_func.
Т.е. реально ли создать какой-нибудь обработчик, который будет вызываться,
если ее выполнение было прервано по throw из inner?? Насколько я понимаю, через
определение специальных классов с деструкторами этого можно добиться -- но
мне интересно, есть ли более короткий путь.

--------------------
В. В чем разница между hardware и software?О. В отличие от второго, по первому можно двинуть кулаком или пнуть ногой.
PM MAIL WWW   Вверх
xvr
Дата 4.2.2008, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(regis @ 4.2.2008,  15:46)
Собственно, возник такой вопрос.
Предположим, что глубоко в последовательности вызовов может быть возбуждено исключение (см. пример):

Код


void inner () {
// ...
throw Exception (...);
}    // inner

void work_func () {
// ...
inner ();
// ...
}    // work_func

void outer () {

try {
    // ...
    work_func ();
    // ...
    } catch (Exception excpt) {
        // обработка excpt здесь...
    };

}    // outer



Вопрос в том, как обработать ненормальное завершение работы work_func.
Т.е. реально ли создать какой-нибудь обработчик, который будет вызываться,
если ее выполнение было прервано по throw из inner?? Насколько я понимаю, через
определение специальных классов с деструкторами этого можно добиться -- но
мне интересно, есть ли более короткий путь.

Ну например так:
Код

void work_func () {
 try {
// ...
inner ();
// ...
 } 
 catch(...)
 {
   // do something
   throw;
 }
}    // work_func

PM MAIL   Вверх
archimed7592
Дата 4.2.2008, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Лучше использовать RAII.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Alek86
Дата 4.2.2008, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(archimed7592 @  4.2.2008,  18:25 Найти цитируемый пост)
Лучше использовать RAII.

даже если в
Код

catch(...)
 {
   // do something
   throw;
 }

в // do something будут TRACE'ы для отладки?
лично мне лень тогда классы добавлять...


--------------------
user posted image    user posted image
PM MAIL   Вверх
archimed7592
Дата 4.2.2008, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Alek86 @  4.2.2008,  18:52 Найти цитируемый пост)
в // do something будут TRACE'ы для отладки?

 smile 
Я переодически использую самописный велосипед LogOnFailure logger(LOG_MSG("bla-bla-bla"));.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Alek86
Дата 4.2.2008, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



прогнал (

а если такая фича и в бусте есть (уверен, есть), то я тоже за RAII во всех случаях (кроме когда уж совсем лень)


--------------------
user posted image    user posted image
PM MAIL   Вверх
archimed7592
Дата 5.2.2008, 03:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Alek86 @  4.2.2008,  19:03 Найти цитируемый пост)
уверен, есть

В бусте я logging capabilities не заметил... Найдёшь - отпишись smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Daevaorn
Дата 5.2.2008, 03:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(archimed7592 @  5.2.2008,  04:03 Найти цитируемый пост)
В бусте я logging capabilities не заметил... Найдёшь - отпишись 

http://www.torjo.com/log2/doc/html/index.html
PM MAIL WWW   Вверх
archimed7592
Дата 5.2.2008, 04:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Daevaorn, интересненько smile.
А есть ли где-нибудь информация о том, почему библиотека не включена в буст(видимо есть какие-то недоработки?), когда ориентировочно собираются включить, собираются ли вообще?


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
regis
Дата 5.2.2008, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 12.12.2005
Где: Москва, Россия

Репутация: 2
Всего: 7



Всем спасибо, кто ответил.

RAII -- это, как я понимаю, и есть то, о чем я говорил выше. С этим подходом есть проблема: в work_func может быть много локальных переменных и соответственно много чего с ним необходимо сделать для корректной финализации. Т.е. завернуть это в конструкторы/деструкторы объекта вряд ли получится.

Более симпатично выглядит идея с re-throw. Однако, можно ли throw без аргументов вызвать из другого места, кроме обработчика в catch?
Например, вот такой подход:

Код


void work_func () {
bool caught_exception = false;

// ... пролог ...


try {
   inner ();
   } catch (Exception excpt) {
    caught_exception = true;
    }

// ... эпилог ...

if (caught_exception) throw;
}    // work_func



-- такое сработает или нет?


--------------------
В. В чем разница между hardware и software?О. В отличие от второго, по первому можно двинуть кулаком или пнуть ногой.
PM MAIL WWW   Вверх
xvr
Дата 5.2.2008, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(regis @ 5.2.2008,  15:26)
Всем спасибо, кто ответил.

RAII -- это, как я понимаю, и есть то, о чем я говорил выше. С этим подходом есть проблема: в work_func может быть много локальных переменных и соответственно много чего с ним необходимо сделать для корректной финализации. Т.е. завернуть это в конструкторы/деструкторы объекта вряд ли получится.

Более симпатично выглядит идея с re-throw. Однако, можно ли throw без аргументов вызвать из другого места, кроме обработчика в catch?

Можно, но это место должно быть вложенно в блок catch (статически или динамически)

Цитата

Например, вот такой подход:

Код


void work_func () {
bool caught_exception = false;

// ... пролог ...


try {
   inner ();
   } catch (Exception excpt) {
    caught_exception = true;
    }

// ... эпилог ...

if (caught_exception) throw;
}    // work_func



-- такое сработает или нет?
Нет

PM MAIL   Вверх
archimed7592
Дата 5.2.2008, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(regis @  5.2.2008,  15:26 Найти цитируемый пост)
такое сработает или нет?

Нет. Сработает такое:
Код

void work_func () {
bool caught_exception = false;
// ... пролог ...
try {
   inner ();
   } catch (Exception excpt) {
      epilog(true);
    }
epilog(false);


void epilog(bool rethrow = false)
{
    // ...

    if (rethrow) throw;
}


К слову, для того и нужен RAII - он отработает и в случае нормального течения обстоятельств, так и в случае исключительной ситуации.


Цитата(regis @  5.2.2008,  15:26 Найти цитируемый пост)
в work_func может быть много локальных переменных и соответственно много чего с ним необходимо сделать для корректной финализации.

Налицо отсутствие гарантии безсбойности - это не есть хорошо и эту ф-цию нужно переписать и/или разбить на несколько ф-ций...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1016 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.