![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
заNILить форму после Close;
ничтожная козявка © (2008-08-21 12:37:00)
Страницы: < 1 2 3 4 5 6 7 8 9 10 >
В некой dll есть функция, показывающая форму. Перед созданием формы, она проверяет ее на NIL:
if not Assigned(Form1) then Form1 := TForm1.Create(AOwner);
также требуется, что бы после закрытия (Close) форма была уничтожена:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
...
Action := caFree;
...
end;
ВОПРОС: как сделать так, чтоб она была не только уничтожена, но и переменная Form1 приняла значение NIL. Т.к. поскольку эта переменная не NIL, при повторной попытке создать форму, ее конструктор
if not Assigned(Form1) then Form1 := TForm1.Create(AOwner);
не вызывается, и в последствии сыпятся AV.
Тын-Дын (2008-08-23 02:02:00) [81]
> Palladin © (22.08.08 20:35) [105]
Хорошо сказано.
Добавлю, что нужно быть очень осторожным и не скатываться к догматизму во всём.
Германн (2008-08-23 00:53:00) [82]
> DVM © (23.08.08 00:09) [107]
>
>
> > А как обратиться к объекту, если ссылка на него тоже по
> > сути переменная, а ее быть категорически не должно?
>
> наверное, как то так:
Всё бы хорошо. Но!
Если нужно хранить список таких объектов, то - облом! Приходится таки вводить совершенно ненужную переменную.
DVM (2008-08-23 00:09:00) [83]
> А как обратиться к объекту, если ссылка на него тоже по
> сути переменная, а ее быть категорически не должно?
наверное, как то так:
program test;
begin
with Object.Create do
Run;
end;
все остальное внутри объекта.
Loginov Dmitry (2008-08-22 23:58:00) [84]> Я уже не один раз высказывался по этому поводу, не вижу
> смысла повторяться.
Извиняюсь, ни разу не слышал.
> Мои соболезнования.
В чем именно? Вроде я в них не нуждался пока.
> Приведи три причины необходимости использования
> DLL with BPL with EXE vs EXE, тогда и обсудим кто MD.
Приводилось не раз. Стоит ли повторяться?
> Сделай все эти переменные, скажем, полями TApplication,
> и будет всем хорошо.
Ага. Типа Application.DecimalSeparator будем чем-то лучше простого DecimalSeparator. Ерундистика какая-то. Просто вбили себе в голову, что глобальные переменные - MD, а обосновывать как собираетесь. Я в курсе, что в некоторых популярных языках понятие "глобальная переменная" отсутствует, есть только "глобальный объект", но по моему мнению, спасибо разработчикам дельфи за то что в их продукте все еще можно обратиться к переменным типа DecimalSeparator минуя дополнительные "ненужные" сущности.
> Проинициализировать что-либо при старте - это еще тот бином
> Ньютона.
В этом-то что Вы плохого видете?
> Ну, и не нужны глобальные переменные.
> Есть нужда - пользуй объекты, со свойствами только для чтения.
А как обратиться к объекту, если ссылка на него тоже по сути переменная, а ее быть категорически не должно?
> Пресловутые "советы" предназначены для совсем уж начинающих
> и хороши лишь тем, что позволяют НАЧИНАЮЩИМ уберечься от
> распространенных ошибок. Но не стоит превращать их в догмы
> - иначе они станут столь же вредны, сколь и полезны. Программист
> просто должен понимать, что, как и зачем он делает, чем
> это хорошо и плохо, какие могут быть подводные камни и как
> их не допустить - и т.д.
+100
> Form1 := nil;
> Form1 := AnyValue;
Зачем здесь AnyValue? Сломать всегда можно было все что угодно.
> Я же указал единственно правильный и надежный путь.
> Зачем же мучаться с глобальными переменными, которые ничего
> не гарантирую, кроме получения AV
Единственный правильный и надежный путь это Screen? А для поиска в Screen необходим перебор по Forms с постоянной проверкой типаif SameText(Screen.Forms[I].Name, 'ИмяФормы') then, и не дай бог я случайно изменю имя формы и забуду его указать в SameText().
> Война бессмысленна ) и она точно - зло.
Это точно!
Palladin (2008-08-22 20:35:00) [85]Опять из безсмысленной темы "определение существования объекта по значению идентификатора" раздули глупокие размышления. А все решение состоит из двух фраз.
1. Синглтон - в делфи не осуществим
2. Дисциплина программиста (самое наиважнейшее) - не забывать сделать так - как написано в [8] и проблемы кончатся.
Однако как всегда имеет факт куча бессмысленных рассуждений начиная со "указатель на указатель - бред" заканчивая "глобальные переменные - вселенское зло".
Игорь любит меня (ну и не только) поучать, все хорошо там где это хорошо выглядит. И он прав между прочим.
"Указатель на указатель бред" - да не всегда. @!!ex пользуется этой этажеркой не для того что бы оперировать через указатель данными указываемого указателя ( :) ), а с целью оперирования переменной, идентификатором. И пофих, что это за переменная, другой ли указатель или целое число.
"Глобальные переменные - вселенское зло" - естественно, если их лепить налево и направо. Но они есть лаконичное(я не говорю, что "правильное в парадигме ООП") решение многих задач. Например настройки приложения. Или глобальный идентификатор класса "среды" исполнения какой либо спецефического приложения, освобождающий от постоянного создания кучи объектов для получения тех или иных параметров и агрегируя их в один.
Война бессмысленна ) и она точно - зло.
{RASkov} (2008-08-22 19:32:00) [86]> [102] McSimm © (22.08.08 19:18)
Ну да... Вроде похоже но не то... проверил - не работает)
Ладно... я все равно с указателями путаюсь, поэтому стараюсь без них...
{RASkov} (2008-08-22 19:19:00) [87]> Знает, вы просто сообщаете ему это в ран-тайм (или не сообщаете, если забыли)
Кстати, да.... Что-то совсем уже не варит башка.... это все указатели виноваты :)
McSimm (2008-08-22 19:18:00) [88]
> {RASkov} © (22.08.08 19:15) [99]
нет, это категорически не то же самое, т.к. вы внесли флаг внутрь самого объекта, от чего предостерегал в этой ветке Юрий.
Ваш класс хранит флаг, в отличие от класса в [1] или [8], которые знают где флаг
{RASkov} (2008-08-22 19:17:00) [89]> FormLink:=nil;
Ну т.е. ее нилим в Дестрой, а в OnClose - caFree...
McSimm (2008-08-22 19:16:00) [90]
> вполне могут быть частью какого-то класса
указатель на свойство ?
> класс TForm1 ничего не знает о переменных Form1_1
Знает, вы просто сообщаете ему это в ран-тайм (или не сообщаете, если забыли)
{RASkov} (2008-08-22 19:15:00) [91]> [98] @!!ex © (22.08.08 19:03)
> Основной(и единственный) плюс в том, что класс TForm1 ничего
> не знает о переменных Form1_1, Form1_2.
Ага... усек это :) Спасибо.
Но что мешает сделать так:
TForm1 = class
public
FormLink: TForm1;
end;
....
Form1: TForm;
Form1:=TForm.Create();
Form1.FormLink:=Form1;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FormLink:=nil;
end;
Вроде то же самое.. только "без" указателей... т.е. без указателей на указатели..)
Или я что-то уже не соображаю... нужно будет проверить? или это действительно тоже самое?
@!!ex (2008-08-22 19:03:00) [92]> [97] {RASkov} © (22.08.08 18:30)
Это контроль ссылок. в коде [91] нет ни одной глобальной переменной, вобщем то.
Form1_1 Form1_2 - вполне могут быть частью какого-то класса, например.
Основной(и единственный) плюс в том, что класс TForm1 ничего не знает о переменных Form1_1, Form1_2. В то время как код в [8] обязует класс знать о глобальной переменной, хранящей указатель на экземпляр класса... Возникает тогда вопрос, а зачем нам вообще класс TForm1? Разве только что ради наследования...
Вобще этот код - это пример обычной работы с классом, который подчищает за собой ссылки на него указывающие.
На С++ с помощью шаблонов и этого метода можно делать самоуничтожающиеся объектые, которые подыхают, когда на них никто больше не указывает + все указатели на объект становятся 0, когда объект умирает.
{RASkov} (2008-08-22 18:30:00) [93]Скачал то что было по ссылке в [76], думал что-то интересное будет...
@!!ex, скажи чесно, как родился такой код? :) Зачем вообще сюда нужно было приделывать эти указатели? (Начиная с [1]...)
Даже с учетом [91] все равно не понятно для чего это все... :(
Не, не подумай ничего плохого, но может я для себя узнаю что нового... может об указателях...
Но по мне, код "ничем" не отличается от [8].... Т.е. отличается - лишней запутанностью. Но это имхо конечно.
Те же глобальные переменные, и в случае с [91] - их более одной...
{RASkov} (2008-08-22 17:45:00) [94]Уже не интересно... последние посты только и состоят из [n]
:)
Юрий Зотов (2008-08-22 17:45:00) [95]> @!!ex © (22.08.08 17:33) [91]
Что ж, будем честными. Код действительно работает. Он действительно основан на том, что написано в 1]. Я был неправ, потому что с самого начала просмотрел код слишком поверхностно. Должен извиниться.
Тем не менее, способ этот, по сути, ничем не отличается от обычного явного использования глобальной переменной - значит, ему присущи все те же самые недостатки. В частности, те, о которых говорил Анатолий.
И даже то, что код будет работать с несколькими формами, практически ничего не меняет. Во-первых, для работы с несколькими формами стоит использовать более подходящие вещи (TComponentList, например). Во-вторых, и в этом случае сохраняются все те же самые недостатки.
{RASkov} (2008-08-22 17:43:00) [96]> [93] @!!ex © (22.08.08 17:39)
Для меня твой код не понятен, поэтому см [90]
И про поля класса читаем в [84]
@!!ex (2008-08-22 17:39:00) [97]> [92] {RASkov} © (22.08.08 17:36)
см [91], Я тчам объяснил, чем мой код отличается от простого использования глобальнйо переменной...
Я вообще всегда думал, что контроль ссылок на объект делается так, как я написал...
вона оказываца как.. эта оказывацца "путанные" указатели... а парни и не знают... побегу сообщать... пускай посмеются.
{RASkov} (2008-08-22 17:36:00) [98]Согласен с [89].
Я тоже путаюсь в указателях, но уверен, что Юрий много болееменя в них понимает...
И еще....
...ни [1] ни [8] ни [75] не сравнятся с [9] :)
@!!ex (2008-08-22 17:33:00) [99]> [89] Юрий Зотов © (22.08.08 17:30)
Так я не понял, мой код работает или нет, он основан на том, что написано в [1] и если это убрать, то он робоать перестанет? Где доказательство нерабоести кода??
Зачем так, почему явно не указывать глоабальную переменную?
Потому что если форм больше чем одна, то мой код будет работать корректно, а ваш - нет.
Могу продемонстрировать примером.
Form1_1:=TForm1.Create();
Form1_1.FormLinkPointer:=@Form1_1;
Form1_2:=TForm1.Create();
Form1_2.FormLinkPointer:=@Form1_2;
if Form1_1<>nil then
//Существует форма 1_1
if Form1_2<>nil then
//Существует форма 1_2
{RASkov} (2008-08-22 17:32:00) [100]> [87] @!!ex © (22.08.08 17:23)
Спор как таковой вообще тут не к месту...
Вариантов решения вопроса в сабже можно привести более чем один...
Я так же свой привел.
Считаю, что в данном случае можно предложить автору свой и высказать(по желанию) -/+ данного варианта.
По мне, я бы никогда, без особой на то необходимости, не стал-бы пользоваться "путанными" указателями....