Форум: "Основная";
Текущий архив: 2004.04.18;
Скачать: [xml.tar.bz2];
ВнизХитрые исключения в конструкторе Найти похожие ветки
← →
IGray (2004-03-27 00:34) [0]Насколько я понял, если в конструкторе объекта
возникает исключение, то сразу автоматически
вызывается деструктор Destroy.
Вопрос: как внутри деструктора понять, что он
вызван аварийно, а не через .Free?
Есть ли какой-то простой и стандартный способ?
← →
Vuk © (2004-03-27 01:44) [1]А какая разница, по какой причине объект разрушается, по ошибке в конструкторе или штатно?
← →
default © (2004-03-27 01:52) [2]IGray (27.03.04 00:34)
если уничт-ешь объект только ты, то можно с пом-ью какого-то флага если нет - то никак не вмешиваясь в код который передёт управление на конструктор в случае неудачно создания объекта
← →
Defunct © (2004-03-27 04:04) [3]Vuk © (27.03.04 01:44) [1]
Разница все же есть.
В деструкторе могут удаляться несозданные объекты, что повлечет за собой еще одно исключение.
← →
TUser © (2004-03-27 07:10) [4]Я не уверен, но предполагаю, что вызов Free ничего не даст. В Free написано что-то типа
if Self <> nil then
Destroy
Пока конструктор не закончил свою работу Self = nil, т.е. при таком вызове можно не вызвать деструктора. Но не уверен.
← →
Vuk © (2004-03-27 10:24) [5]to Defunct © (27.03.04 04:04) [3]:
>В деструкторе могут удаляться несозданные объекты, что повлечет
>за собой еще одно исключение.
Угу, а проверить что-то, что пытаемся удалить на предмет существования религия не позволяет? Причем проверять желательно всегда - даже при нормальном завершении.
to User © (27.03.04 07:10) [4]
>Пока конструктор не закончил свою работу Self = nil
Self не nil уже при входе в конструктор. Для объектов-членов класса вызов Free не даст ничего по другой причине - все внутренние данные экземпляра перед вызовом конструктора инициализируются нулями, поэтому для объектов там будет nil, что и сделает вызов Free безопасным.
← →
IGray (2004-03-27 12:40) [6]
> Vuk © (27.03.04 01:44) [1]
> А какая разница, по какой причине объект разрушается, по
> ошибке в конструкторе или штатно?
Дело в том, что мой напарник очень хочет засунуть в Destroy дополнительную функциональность, типа сохранения состояния объекта в Ini-файл и т.п. Мне кажется, что это криво - а что общественность думает?
P.S. Всем спасибо за ответы!
← →
Anatoly Podgoretsky © (2004-03-27 13:48) [7]Defunct © (27.03.04 04:04) [3]
Не надо так делать.
← →
Vuk © (2004-03-27 16:19) [8]to IGray (27.03.04 12:40) [6]:
>что мой напарник очень хочет засунуть в Destroy дополнительную
>функциональность, типа сохранения состояния объекта в Ini-файл
Стоит его всеми силами отговаривать. Деструктор - это такая штука, что обратного пути нет, если туда попали, то альтернатив разрушению объекта нет. То есть Вы не сможете обработать ошибки, которые могут возникнуть в результате работы того самого дополнительного функционала и восстановить состояние объекта. А ошибки при сохранении состояния в ini, например, сами понимаете, какие могут возникнуть. Если уж сохранять, то перед разрушением, в BeforeDestruction. А вообще, все от конкретной ситуации зависит...
← →
Piter © (2004-03-27 17:07) [9]Vuk (27.03.04 16:19) [8]
Стоит его всеми силами отговаривать
ну почему. Мне кажется это имеет вполне определенную функциональную цель. Если будешь знать, какие значения были у полей объекта до вызова исключения в конструкторе (если исключение не специально генерируемое, то есть произошла нештатная ситуация) - это может дать определенную пищу для размышлений разработчику по выявлению ошибки
← →
Vuk © (2004-03-27 17:43) [10]to Piter:
>ну почему.
Угу. Сохраняем, значит, данные в файл. Из деструктора. И тут ХРЯСЬ, место на диске кончилось или еще что. Состояние объекта неопределено, ибо непонятно, в каком месте навернулось и что уже к этому моменту успели прибить, а что нет. Он не разрушился до конца и уже не находится в том же состоянии, что и до вызова деструктора.
Кстати, тут еще проблема дизайна вылезает. Предположим, что есть у нас класс, который сохраняет что-то из деструктора. Сделали его наследник, который добавляет еще один внутренний объект, состояния которого нужно хранить. Причем хранить желательно не отдельно от всего того, что определено в предке. Так вот, вопрос. Где (в каком месте программы) должен сохраняться такой объект и когда уничтожаться?
← →
Defunct © (2004-03-27 20:55) [11]Anatoly Podgoretsky © (27.03.04 13:48) [7]
Эввв, а я ничего не делал... Не бейте меня, пожалуйста (C) бойцовский клуб
← →
Тимохов © (2004-03-28 11:41) [12]зачем это понимать.
просто надо писать всегда надежно - например, перед очисткой tlist, проверить, что list <> nil (if list <> nil then for i := 0 to list.count-1 do tobject(list[i]).free)
и поручить деструктуру только освобождение ресурсов - никакой функциональности, это путь к ошибкам.
← →
Anatoly Podgoretsky © (2004-03-28 12:31) [13]Конечно можно, но путь чреватый своими последствиями. Поэтому должен делаться очень осторожно и лучше в обработчике OnDestroy.
← →
Тимохов © (2004-03-28 12:33) [14]
> Anatoly Podgoretsky © (28.03.04 12:31) [13]
если вы мне, то я про классы говорил, а не про формы и дм.
← →
Anatoly Podgoretsky © (2004-03-28 12:35) [15]Вообзе то не персонально, но разницы не вижу, кроме терминологии.
← →
Тимохов © (2004-03-28 12:37) [16]Анатолий, Вы меня всегда поражали глубиной копания, но непонятностью в понимании Вас.
Что значит
> но разницы не вижу, кроме терминологии.
В классах OnDestroy же нет?
← →
Vuk © (2004-03-28 14:04) [17]Кстати о птичках в виде OnDestroy. Эти обработчики (где они есть)вызываются из BeforeDestruction. Это единственное место, где можно штатно и правильно отменить разрушение экземпляра при помощи возбуждения исключения. Поэтому в этих обработчиках и методе BeforeDestruction лучше воздержаться от удаления объектов, т.к. иначе можно получить неработающий класс, если по каким-то причинам разрушение будет отменено.
← →
Тимохов © (2004-03-28 14:10) [18]предлагаю сухой остаток в качестве фака.
1. если нужно отменить разрушение объекта, то делать это надо в BeforeDestruction.
2. в BeforeDestruction не стоит освобождать занятые объектом ресурсы
3. освобождать занятые объектом ресурсы нужно в деструкторе объекта
4. в деструкторе отменить разрушение объекта нельзя.
← →
KSergey © (2004-03-28 14:15) [19]в 4 важным, по-моему, является несколько другое (возможно, это 5?)
Деструктор должен быть спроектирован так, чтобы в нем не возникли исключения, по крайней мере - необработанные.
← →
Vuk © (2004-03-28 14:16) [20]to Тимохов:
>в деструкторе отменить разрушение объекта нельзя.
Немножко поправлю. На одну букву. :o)
Отменить-то можно. Точно так же, возбудив исключение. Но только, что при этом получится - науке неизвестно. Так что можно сказать, что не отменить нельзя, а отменять нельзя.
← →
Тимохов © (2004-03-28 14:16) [21]
> KSergey © (28.03.04 14:15) [19]
другой вопрос, как эти исключения обрабатывать.
← →
Тимохов © (2004-03-28 14:19) [22]
> Vuk © (28.03.04 14:16) [20]
хорошая поправка :))))
Кстати вопрос всем:
все-таки как кто обрабатывает исключения в деструкторе?
Ответ в стиле - надо проектировать так, чтобы исключений в деструкторе не было не подходит, т.к. защититься от всех возможных ошибок не возможно (например, от выключения компьютера :)))))).
← →
KSergey © (2004-03-28 14:19) [23]> [21] Тимохов © (28.03.04 14:16)
> другой вопрос, как эти исключения обрабатывать.
По выше исписанному понял так, что их глушить надо на корню, дабы деструктор дорабатывал до конца. Возможно, ошибаюсь.
← →
KSergey © (2004-03-28 14:20) [24]> [22] Тимохов © (28.03.04 14:19)
При выключении компа (равно как и от кнопки ресет) исключения не возбуждаются.
← →
Тимохов © (2004-03-28 14:24) [25]
> KSergey © (28.03.04 14:20) [24]
> > [22] Тимохов © (28.03.04 14:19)
>
> При выключении компа (равно как и от кнопки ресет) исключения
> не возбуждаются.
Да шутка это конечно была.
Может был не удачный пример того, что защититься от всего на свете нельзя.
Интересно было кто как решает этот вопрос.
← →
Vuk © (2004-03-28 14:26) [26]К сожалению, особо сделать что-то с исключениями в деструкторе не получится. Ну если только что писать все так, как будто их нет и дать возможность проявляться ошибкам. Дело в том, что заглушив исключение легко потерять информацию о том, что ошибка вообще имела место и что-то пошло не так при попытке разрушении какого-либо объекта. А выход, действительно, лежит в правильном проектировании.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.04.18;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.038 c