Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.039 c
7-1077017287
Kremen
2004-02-17 14:28
2004.04.18
МАС-адрес


7-1077025317
L.evil
2004-02-17 16:41
2004.04.18
Как програмнов в XP изменить/добавить учётную запись


7-1077105050
SPeller
2004-02-18 14:50
2004.04.18
Вопрос по РЕ формату


1-1081010156
DvD
2004-04-03 20:35
2004.04.18
как установить свой ScreenSaver?


7-1076568590
alex_24
2004-02-12 09:49
2004.04.18
Минимизация формы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский