-
У меня переменные многократно используются. То удаляются, то добавляются. Можно сильно запутаться, а так жесткая напоминалка об обнулении. И от класса объекта не зависит никак. И код сократился в разы - не надо помнить где и какой объект инициализирован.
//Вариант 0 (Как было) gVariant.Free; gVariant := nil; gObject.Free; gObject := nil; gGrid.Free; gGrid := nil;
//Вариант 1 FreeAndNil(@gVarious); FreeAndNil(@gObject); FreeAndNil(@gGrid);
//Вариант 2 gVarious.Free(@gVarious); gObject.Free(@gObject); gGrid.Free(@gGrid);
//Вариант 3 (самый удобный) Scene.DestroyObjects;
-
> dmk © (10.12.18 12:26) > > Всем привет! > Возможно ли сделать так, чтобы объект при уничтожении сам > себе присваивал nil?
Никакой объект не имеет "объективной" возможности узнать сколько пользовательская программа сделала на него ссылок. Так что вопрос дурной. Вторая "дурность" вопроса заключается в самой "якобы" необходимости обниливать какую-то ссылку.
-
Это конечно ИМХО, но вполне обоснованное.
-
> Германн © (11.12.18 02:49) [22]
чем-то это мне напоминает борьбу с GOTO )
-
procedure TZObject.Free(AObj: PObject);
А вот зачем указатель? TObject - уже указатель на объект же. Точно требуется еще и указатель на этот указатель?
-
Если хочется переприсвоить значение самой переданнйо переменной - её просто надо передать по ссылке, т.е.
procedure TZObject.Free(var AObj: TObject);
Как-то оно прямее, понятнее, добрее
-
>А вот зачем указатель? У меня массив указателей на переменные, а не на адреса объектов. Инчае в параметрах придется писать обертку PObject(MyObjectType), а он не пропустит, т.к. строгая типизация, а указатели пропускает. Я уже все варианты перепробовал. Так проще всего:
type PVar = ^TVar; TVar = Pointer;
procedure TZObject.Free(AVar: TVar); begin inherited Free;
//Очистка переменной if (AVar <> nil) then if (PVar(AVar)^ <> nil) then PVar(AVar)^ := nil; end;
и вызов
FObjects[i].Free(@FObjects[i]^); Все внешние переменные прилинкованные к массиву обнуляются и освобождаются.
-
Добавляем ссылку на переменную:
Scene.AddObject(@gObject); Удаляем ссылку из массива указателей^
FObjects[i].Free(@FObjects[i]^); Освобождаем объект и очищаем переменную:
FreeAndNil(@gVarious);
Очистка:
procedure FreeAndNil(AVar: TVar); begin if (AVar <> nil) then if (PVar(AVar)^ <> nil) then begin PObject(AVar)^.Free; PVar(AVar)^ := nil; end; end;
-
У меня массив не FObjects: array of TZObject, а FObjects: array of PZObject; Ссылки на переменные и на другие массивы, которые уже TZObject.
-
> dmk © (11.12.18 11:49) [26] > Все внешние переменные прилинкованные к массиву обнуляются и освобождаются.
Чего??
> dmk © (11.12.18 12:08) [28] > У меня массив не > FObjects: array of TZObject, а > FObjects: array of PZObject;
Это понятно, про это и вопрос.
> dmk © (11.12.18 12:08) [28] > Ссылки на переменные и на другие массивы, которые уже TZObject.
Но зачем? вот что мне не понять. Обратите внимание: в VCL не смотря на то, что есть понятие "владелец объекта", который этот объект удаляет, кстати, совершенно успешно, и при всём при этом в VCL никаких PObject - нет совершенно. Ибо не нужны они. Правда-правда.
-
> dmk © (11.12.18 11:55) [27]
Если честно - дичь какая-то. Если бы вы обрисовали задачу, которую всеми этими изворотами решаете - уверен, вам бы подсказали более прямой и понятный путь решения задачи.
Это уже не говоря про то, что FreeAndNil() есть штатная же, и она иначе несколько устроена в смысле типов
-
>Если бы вы обрисовали задачу, которую всеми этими изворотами решаете - >уверен, вам бы подсказали более прямой и понятный путь решения задачи. В [18] описаны варианты создания объектов. Из файла [1], процедурная генерация [2], генерация массивов [3]. Над объектами проводится куча действий: 1. Трансформация 2. Перекраска 3. Текстурирование 4. Слияние 5. Отрисовка и т.д. и т.п. Действия в цикле однотипные, но доступ к объектам или через массив ссылок или через переменную. Нужно и так и так. Кол-во объектов может быть и сотни и тысячи и десятки тысяч. Переменных может быть также несколько десятков. Зачем мне листинги с удалением персональных переменных? Проще добавить в массив и потом махом все удалить. Поведение объектов хаотичное. Это 3D-сцена в общем. По ссылкам в массиве удобно все удалить или удалить выборочно.
-
Из написанного вами вот что не понятно: зачем массив указателей на (сслыки) объекты? Да, я умышлено пишу "ссылки на объекты", ибо TObject - эти именно ссылка на объект по своей сути, ну или, более честно, указатель. Уже указатель!
> Действия в цикле однотипные, но доступ к объектам или через массив ссылок или через переменную.
Это вы так сделали, и это из кода видно. Но зачем? смысл какой всего этого? зачем вам ссылки непременно понадобилось в разных местах хранить? Кстати, почему бы не хранить целочисленные индексы в массиве объектов? зачем указатели? Индексы имеют тот плюс, что их можно контролировать. А указатели - нельзя, т.к. нет возможности достоверно узнать указывает указатель на валидное значение или на невалидное в памяти.
-
-
Не понятно (мне), но определённо красиво! )
PS Расширение для файла .obj - режет глаз, конечно (ибо уже имеет своё устоявшееся значение в компьютерном мире). Но чем заменить - не знаю.
-
>.obj - режет глаз Зато бесплатно. Это открытый формат. Бесплатных очень мало.
-
> массив указателей на переменные еще чудесатее а вот этот новый фри скорее всего напрочь и эту переменную стирает, прям из кода))
-
По ссылкам в массиве удобно все удалить или удалить выборочно.
а теперь я начинаю хотеть хранить ссылки на чудесный самоубивающийся класс в свойствах другого класса.
привет, тебе, пернатый архитектор у которого не болит голова.
-
> У меня массив указателей на переменные, а не на адреса объектов. повторю ранее говорившееся, читай внимательно - переменная объекта, это уже указатель. нет смысла в указателе на указатель, первый и так прекрасно на объект указывает, без дополнительных посредников. > Так проще всего: > type > PVar = ^TVar; > TVar = Pointer; > > procedure TZObject.Free(AVar: TVar); > begin > inherited Free; > > //Очистка переменной > if (AVar <> nil) then > if (PVar(AVar)^ <> nil) then PVar(AVar)^ := nil; > end;
... если нормально, то как мне кажется попроще, а делать будет то же самое. TObject вместо TVar чтобы, ты сам упоминал, без приведений типов, сойдет для всех потомков procedure TZObject.Free(var AVar: TObject);
begin
inherited Free;
AVar:= nil;
end;
-
> Прикольно, трупы сами себе могилу роют.
В нормальных языках это давно так реализовано.
> Возможно ли сделать так, чтобы объект при уничтожении сам > себе присваивал nil? > Или надо FreeAndNil использовать?
Нельзя. Embarcodere уже который год тянут кота за яйца, но автосборку мусора сделать не могут. Да проще свой препроцессор написать.
|