Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Эксепшн глобального объекта / 8 сообщений из 8, страница 1 из 1
17.12.2004, 21:09
    #32833130
icanfly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
Интересует что делать если глобальный объект сгенерировал эксепшн? Где его перехватывать?
...
Рейтинг: 0 / 0
17.12.2004, 21:28
    #32833141
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
может я туплю, но глобальнее main исключения не возникнет :-)
взять все в

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
...main(...)
{
 try
 {
   ...
 }catch(...)
 {
   ...
 }
}
хотя, кжется, с конструкторе или деструкторе глобального объекта исключение так не поймаешь
...
Рейтинг: 0 / 0
17.12.2004, 22:16
    #32833165
icanfly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
Вот оно как раз в деструкторе..
Я жертва неправильного дизайна? :)
...
Рейтинг: 0 / 0
17.12.2004, 22:19
    #32833167
Man555
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
согласен с alex_k
объект где-то конструируется... приведи пример
...
Рейтинг: 0 / 0
17.12.2004, 22:34
    #32833174
icanfly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
Объект глобальный. И конструируеться он конечно, ещё до того как в мэйн попадаем. Деструктор выглядит примерно так:

CShopBase::~CShopBase(void)
{
Save ();
}

Save может сгенерить эксепшн. Обрабатывать его прямо в деструкторе нехочеться :)
...
Рейтинг: 0 / 0
18.12.2004, 13:28
    #32833364
dwl
dwl
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
1) никогда не следует допускать исключений в деструкторе, или НЕ ВЫПУСКАЙТЕ их
2) можно метод SAVE вызывать явно до вызова конструктора, например в main
3) а еще лучше отказаться от глобального объекта и написать Синглетон для этого типа. Тогда все будет в твоих руках
...
Рейтинг: 0 / 0
18.12.2004, 17:31
    #32833475
Man555
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
dwl прав. вызывай его перед уничтожением, если, конечно, он у тебя публичный. в противном случае, ловить исключение надо в деструкторе, поскольку save изменяет состояние CShopBase прямо пере тем как уйти в небытие, поэтому отлов исключения вне этого объекта не имеет ни малейшего смысла (зачем, если он dead? завещание? :-) ). Поправте меня, если не прав.
...
Рейтинг: 0 / 0
18.12.2004, 19:50
    #32833516
dwl
dwl
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксепшн глобального объекта
Обрабатывать исключение внутри деструктора нужно еще и по другой ИМХО более веской причине. Напомню, что деструктор вызывается, когда объект выходит из области видимости, или явно, или когда происходит "обработка" исключения, т.е. раскручивание стека.

Чем же грозит исключение внутри деструктора? Смертью программы. Смотрим примеры:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
void my_func(){
  TBadObject* bad; // это объект в классе которого определн деструктор с исключением
  ....
  bad = new TBadObject;
  ...
  try{
  }
  catch(...){
    cout << "все плохо!"; // тоже кстати говоря небезопасно
    delete bad; // арамагедон
  }
}

просто примерчик. перед освобождением памяти вызывается деструктор, а он генерит новое исключение, которое остановит по сути раскрутку стека и не даст освободится памяти. Тоже самое будет если объект будет распологаться не в куче.

возьмем другой пример. Не буду его писать - просто перепишите предыдущий пример, но как массив "плохих" объектов. Теперь представьте что вызывая деструкторы каждого эелемнта массива, где-то в середине деструктор дал исключение. Массив будет не "освобожден", другие элементы тоже, раскрутка стека для других элементов созданных ДО массива остановится.

еще пример.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
class TVeryBadObject {
  TBadObject __bad;
  int* __big;
public:
  TVeryBadObject() : __bad(), __big( new int[VERY_BIG_SIZE] ) {}
  ~TVeryBadObject(){ delete [] __big; }
}

тут двоякая и даже троякая ситуация. Если исключение произойдет при контруировании объекта, тогда все успевшие создаться объекты будут уничтожаться. Допустим память выделить не удалось, и мы попытаемся удалить плохиша, а он не удалится! На развале этого объекта все остановится, просто представьте, если бы был массив "плохишей" ? Двоякость возникает при рядовом вызове деструкора владельца, а троякость при наследовании 8-))))

В случае с глобальным объектом - упаси вас бог их создавать - все усугубляется неопределенностью вызова конструкторов глобальных обхектов. Т.к. убиваться они будут в порядке LIFO через функцию atexit кажется, а вызов конструкторов для глобальных объектов не определен стандартом. Поэтому неясно кто умрет первым а кто последним. И ставить try catch в main не имеет смысла, потому что область видимости глобальных переменных больше области видимости main, т.к. по определению они декларируются выше.

Отсюда вывод(Ы)
1) не создавайте глобальных объектов, заменяйте их синглтонами
2) не выпускайте исключения из деструктора
3) не пишите ОПАСНЫХ обработчиков catch, т.к. см правило (2)
4) не пытайтесь спастьи ситуацию обработкой СМЕРТИ объекта за счет внешнего try catch - до него дело не дойдет. поэтому см правило (2)
5) не пытайтесь переопределить действия функции atexit - будет пушистый и большой ....8-)))

вооот. Еще нужны примеры почему исключения нельзя выпускать из деструктора? Их есть у меня...
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Эксепшн глобального объекта / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]