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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Исключение нужно бросить в конструкторе. Как поступаете в таких случаях? 
V
    Опции темы
 
Исключения, бросаемые в конструкторе, - что вы с ними делаете?
ничего не делаю: надо бросить - бросаю [ 24 ]  [48.98%]
стараюсь не бросать исключений в конструкторах, но иногда приходится [ 11 ]  [22.45%]
никогда не бросаю исключений в конструкторах [ 8 ]  [16.33%]
бросаю исключения только в конструкторах [ 1 ]  [2.04%]
не выбрасываю исключение, а делаю что-то другое (написать, что именно). [ 5 ]  [10.20%]
Всего проголосовавших: 49
В этом опросе возможен один вариант ответа
Гости не могут голосовать 
bsa
Дата 10.1.2008, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 63
Всего: 196



Цитата(UnrealMan @ 10.1.2008,  20:18)
А дальше ловим его в том же деструкторе и обрабатываем функтором-обработчиком (при этом деструктор не знает, как именно должна происходить обработка исключения).

Тут речь идет о выкидывании исключений наружу. Если обработка осуществляется внутри функции (как конструктора, так и деструктора), то проблем вообще никаких нет.
PM   Вверх
JackYF
Дата 10.1.2008, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



UnrealMan, да, ты нереальный человек smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 10.1.2008, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


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

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



Цитата(UnrealMan @  10.1.2008,  20:18 Найти цитируемый пост)
А дальше ловим его в том же деструкторе и обрабатываем функтором-обработчиком (при этом деструктор не знает, как именно должна происходить обработка исключения).

Как же я сразу не догадался в чём подвох smile.

В принципе, для записи логов и т.п. решение очень даже красивое(тот самый throw; во внешней ф-ции, да? 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   Вверх
baldina
  Дата 10.1.2008, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 32
Всего: 101



Цитата

1. деструктор вызовется
2. деструктор не вызовется

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

Добавлено через 3 минуты и 1 секунду
ступил - до конца не дочитал  smile

Добавлено через 6 минут и 22 секунды
главного то не написал:
надо бросить - бросаю. 
хотя конечно не ожидая исключений как-то комфортнее
PM MAIL   Вверх
UnrealMan
Дата 10.1.2008, 20:48 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(archimed7592 @  10.1.2008,  20:25 Найти цитируемый пост)
В принципе, для записи логов и т.п. решение очень даже красивое(тот самый throw; во внешней ф-ции, да?  smile. 

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

Описание handler-а и деструктора выглядит примерно так:

Код

struct Handler
{
    void operator ()(параметры)
    {
         try
         {
              throw;
         }
         catch (поехали обрабатывать исключения)
         {
         }
         ....
    }
};

~T()
{
    try
    {
        for (;;)
            try
            {
                ...
            }
            catch (...)
            {
                // handler имеет тип boost::function<void (параметры)>
                handler(параметры); // может бросить исключение в виде объекта класса HandlingFailed
            } // если не бросает, повторяем попытку :-)
    }
    catch (HandlingFailed &)
    {
    }
}

Кстати, конструктор тоже может следовать этой методике. Зачем сразу сдуваться, если можно вежливо попросить пользователя разрешить проблему и доконструроваться себе дальше? smile

Это сообщение отредактировал(а) UnrealMan - 10.1.2008, 21:11
PM MAIL   Вверх
JackYF
Дата 10.1.2008, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



UnrealMan, честно говоря, не понял сиих конструкций.  smile .
При возникновении нештатной ситуации в деструкторе я лучше сделаю запись в логах, что всё плохо или не очень, и выйду из деструктора.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
UnrealMan
Дата 10.1.2008, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(JackYF @  10.1.2008,  21:12 Найти цитируемый пост)
При возникновении нештатной ситуации в деструкторе я лучше сделаю запись в логах, что всё плохо или не очень, и выйду из деструктора.

Зачем так пессимистично поступать? Вдруг нештатную ситуацию удастся разрешить и во вполне штатном режиме выполнить функции деструктора?

Добавлено @ 21:20
Цитата(JackYF @  10.1.2008,  21:12 Найти цитируемый пост)
UnrealMan, честно говоря, не понял сиих конструкций. 

Шо не понятно? Выбросили исключение, поймали, вызвали обработчик, в обработчике исключение сгенерировали повторно и обработали smile

Добавлено @ 21:23
Класс, которому принадлежит деструктор, об обработчике почти ничего не знает - т.е., например, способ обращения к пользователю не будет захардкоден в деструктор, и это есть хорошо smile 

Это сообщение отредактировал(а) UnrealMan - 10.1.2008, 21:24
PM MAIL   Вверх
JackYF
Дата 10.1.2008, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(UnrealMan @  10.1.2008,  20:19 Найти цитируемый пост)
Шо не понятно?

Как эта штука будет масштабироваться на несколько деструкторов. Да и вообще - мой мозг на сейчас отказывается воспринимать эту структуру кода. 


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 10.1.2008, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


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

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



Цитата(JackYF @  10.1.2008,  21:43 Найти цитируемый пост)
Да и вообще - мой мозг на сейчас отказывается воспринимать эту структуру кода.

Запусти:
Код

void f1();
void f2()
{
  try
  { throw 0; }
  catch(...)
  { f1(); }
}

void f1()
{
  try
  { throw; }
  catch(...)
  { std::cout << "hi" << std::endl; }
}



--------------------
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   Вверх
UnrealMan
Дата 10.1.2008, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(JackYF @  10.1.2008,  21:43 Найти цитируемый пост)
Как эта штука будет масштабироваться на несколько деструкторов.

Тут не стоит такая задача.
Желательно, чтобы обработка исключений и функционал деструктора были разнесены, а не перемешивались (знакомая парадигма, не так ли?). Вот на это данный код и нацелен.
PM MAIL   Вверх
JackYF
Дата 10.1.2008, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(archimed7592 @  10.1.2008,  20:47 Найти цитируемый пост)
try
  { throw; }
  catch(...)

так, уже лучше. Каково предназначение этого куска кода?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
UnrealMan
Дата 10.1.2008, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(JackYF @  10.1.2008,  22:02 Найти цитируемый пост)
так, уже лучше. Каково предназначение этого куска кода? 

Т.к. мы хотим заставить исключения обрабатываться в этих catch-блоках (внутри функции/функтора-обработчика), то исключение надо генерировать внутри соответствующего try-блока. А поскольку изначально исключение генерируется не в этом try-блоке, а в другом месте (где-то в деструкторе), то нужно поймать это исключение и повторно сгенерировать его внутри данного try-блока, а иначе внутрь этого try-блока оно никак не попадёт. Я понятно выражаюсь? smile
PM MAIL   Вверх
archimed7592
Дата 10.1.2008, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


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

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



Цитата(JackYF @  10.1.2008,  22:02 Найти цитируемый пост)
Каково предназначение этого куска кода? 

Эммм, ок, дабы немного придать смысл коду:
Код

void handler();
void foo()
{
  try
  {
      if (std::rand() % 2)
        throw 0;
      else
        throw "0";
  }
  catch(...)
  { handler(); }
}
void handler()
{
  try
  { throw; }
  catch(int i)
  { std::cout << "int = " << i << std::endl; }
  catch(const char *s)
  { std::cout << "string = " << s  << std::endl; }
  catch(...)
  { std::cout << "unknown" << std::endl; }
}



--------------------
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   Вверх
JackYF
Дата 10.1.2008, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Теперь понял, спасибо вам обоим.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Mayk
Дата 11.1.2008, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



есть мнение что в подобном случае следует заводить ф-цию init и вызывать её, дабы в случае чего деструктор уничтожал объект.
вообще стараюсь исключения не кидать. 
а если кидать то в основном из ASSERT'ов.



--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Страницы: (5) Все 1 2 [3] 4 5 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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