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

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

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

Save может сгенерить эксепшн. Обрабатывать его прямо в деструкторе нехочеться :)
...
Рейтинг: 0 / 0
Эксепшн глобального объекта
    #32833364
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
1) никогда не следует допускать исключений в деструкторе, или НЕ ВЫПУСКАЙТЕ их
2) можно метод SAVE вызывать явно до вызова конструктора, например в main
3) а еще лучше отказаться от глобального объекта и написать Синглетон для этого типа. Тогда все будет в твоих руках
...
Рейтинг: 0 / 0
Эксепшн глобального объекта
    #32833475
Man555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dwl прав. вызывай его перед уничтожением, если, конечно, он у тебя публичный. в противном случае, ловить исключение надо в деструкторе, поскольку save изменяет состояние CShopBase прямо пере тем как уйти в небытие, поэтому отлов исключения вне этого объекта не имеет ни малейшего смысла (зачем, если он dead? завещание? :-) ). Поправте меня, если не прав.
...
Рейтинг: 0 / 0
Эксепшн глобального объекта
    #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
8 сообщений из 8, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Эксепшн глобального объекта
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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