-
>sniknik © (11.12.18 20:40) [38] Так только для переменной подходит. Через PObject еще из массива освобождать можно. Где AVar - указатель на ячейку массива, а AVar^ доступ к переменной в ячейке, т.к. в ячейке хранится ссылка на другую переменную. Запутано конечно, но работает норм. В упрощенном виде: 1. Доступ к переменной - PVar(AVar)^. 2. Доступ к ячейке массива в которой хранятся ссылки на переменные - PObject(AVar^)^.
-
>Да проще свой препроцессор написать. Уже хочется свой компилятор если чесно. Куча ограничений кругом.
-
>Embarcodere уже который год тянут кота за яйца, но автосборку мусора сделать не могут. Они вам продадут эту фичу лет через 5 в версии 11.4. Это же маркетинг.
-
вы как переменные в ячйку запихали? ))
-
мое имхо, что можно делать, что хочешь, лишь бы тебе было понятно и полезно. domain specific language, ёлки.
-
>вы как переменные в ячйку запихали? )) Для этого надо 2 высших иметь. У вас есть 2 высших?
-
тут 2 мало, тут надо щтук пять а лучше шесь, но у меня семь, так что все в порядке
-
-
вы не обсуждаете а лепите. что то издалека напоминающее что то типа турбо паскаль )) со всвоими велосипедами в виде эти фри[энднил], ну и венцом из переменных в ячейках. и можно тольео повторить -
> дичь какая-то
-
> Sha © (11.12.18 09:24) [23] > > > Германн © (11.12.18 02:49) [22] > > чем-то это мне напоминает борьбу с GOTO )
Почему только напоминает? Это та же самая борьба только на другом фронте. :)
-
> Sha © (11.12.18 09:24) [23] > > > Германн © (11.12.18 02:49) [22] > > чем-то это мне напоминает борьбу с GOTO )
Ведь использование GOTO подразумевает использование Label, которые можно ставить в коде что в паскалевской, что в Дельфийской программе практически где угодно (возможно не везде, но я это не проверял). И IDE/Компилятор не могут уверенно указать на принципиальную ошибку алгоритма/программы. Т.о. вся ответственность за использование такого полностью ложится на его автора. Но готов ли автор её принять?
-
> Германн © (12.12.18 02:21) [50]
И GOTO, и FreeAndNil обычно не требуются программисту.
Но в тех редких случаях, когда их применение действительно имеет смысл, они способны существенно упростить алгоритм или повысить скорость.
-
>>sniknik © (11.12.18 20:40) [38]> Так только для переменной подходит. Через PObject еще из массива освобождать можно. да, я понял, у тебя в объекте указатель на себя же, на внешнюю переменную с собой(которая тоже указатель). по нему "обниляеш" именно внешнюю. поначалу сбило то, что ты в примере его во Free переменной передаешь, а не берешь из внутренних переменных. вообще, "претензия" к такому подходу только в том что это громоздко и сложно для понимания (самому через пару лет поменять понадобится...). лучше бы как то поменять логику, обойтись например без внешней вообще, работать со спискам объектов, в котором их уничтожение уже реализовано (приснопамятный сборщик мусора... ), ну вот, тут адрес внешний внутрь передается, но смысла в этом не вижу, если уж нужна для работы используй и бросай без Free, список потом сам позаботится. type
TMyObject = class(TObject)
Obj: TMyObject;
destructor Destroy; override;
end;
destructor TMyObject.Destroy;
begin
inherited;
Form1.Edit1.Text:= '!!!!!!'
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
ObL: TObjectList;
pO: TMyObject;
begin
ObL:= TObjectList.Create;
try
ObL.Add(TObjectList.Create);
ObL.Add(TObject.Create);
i := ObL.Add(TMyObject.Create);
pO:= TMyObject(ObL.Items[i]);
pO.Obj:= @pO;
finally
ObL.Free;
end;
end;
-
>вообще, "претензия" к такому подходу только в том >что это громоздко и сложно для понимания Так я без наставлений в народ вышел. Просто спросил, а меня уже запинали. У меня 3D-эшечка. 3D-объекты вещь комплексная и создаются у меня в разных местах и разными методами. Модифицируются также в разных местах и даже в разных модулях. Загружаются в массивы или переменные. Вот например, система частиц - это же массив созданных процедурно или загруженных из файла объектов. У них даже классы обработки разные. Только общий предок TZObject. Частицы находятся в одном массиве. Объекты взаимодействия в другом или вообще в отдельной переменной. У меня и так перерасход памяти жуткий идет, а вы мне предлагаете еще один массив с T-классом сделать. Двойное существование объекта в общем то не нужно. Поэтому я и придумал массив ссылок (сцена). Может как то иначе этот массив можно представить?
У меня так сделано:
type PZScene = ^TZScene; TZScene = class private FObjects: array of PZObject; FNumObjects: Integer; FSceneStatistic: TSceneStatistic; procedure SetObject(Index: Integer; Value: PZObject); inline; function GetObject(Index: Integer): PZObject; inline; public constructor Create; destructor Destroy; override; procedure AddObject(Value: PZObject); procedure ChangeTarget(ATarget: PBitmap64); procedure DeleteObject(Value: PZObject); procedure DestroyObjects; procedure DrawObjects; function GetMaxObjectsDepth: Single; function GetDepth: Single; procedure InverseDraw; function LowIndex: Integer; inline; function HighIndex: Integer; inline; function NumJoins: Integer; function NumPoints: Integer; function NumTriangles: Integer; function ObjectExist(Value: PZObject): Boolean; inline; function ObjectIndex(Value: PZObject): Integer; inline; procedure Reset; procedure SetFill(Value: Boolean); procedure SetStroke(Value: Boolean); procedure SetOpacity(Value: Single); procedure ScaleObject(Value: PZObject; F: Single); procedure ScaleObjects(Value: Single); procedure SetCheckerColors(Args: array of TColor32); procedure SetHSVColors(AOrient: TPlaneType); procedure SetObjectFirst(Value: PZObject); procedure SetRandomColors; procedure UpdateStatistic; //--- property Objects[Index: Integer]: PZObject read GetObject write SetObject; property NumObjects: Integer read FNumObjects; property Statistic: TSceneStatistic read FSceneStatistic; end;
procedure TZScene.AddObject(Value: PZObject); begin if (Value^ <> nil) then begin if not ObjectExist(Value) then begin Inc(FNumObjects); SetLength(FObjects, FNumObjects); FObjects[High(FObjects)] := Value; end; end; end;
procedure TZScene.DeleteObject(Value: PZObject); var i, k: Integer; Found: Boolean;
begin if (FNumObjects > 0) and (Value <> nil) then begin Found := False; k := LowIndex;
for i := LowIndex to HighIndex do begin if FObjects[i] = Value then begin FreeAndNil(@Value^); Found := True; Continue; end else //Пропустим удаленный объект begin FObjects[k] := FObjects[i]; Inc(k); end; end;//for
FNumObjects := k; SetLength(FObjects, FNumObjects);
//Если не найден, то удаляем объект вне сцены if (not Found) then FreeAndNil(@Value^); end; end;
procedure TZScene.DestroyObjects; var i: Integer;
begin if (FNumObjects > 0) then begin for i := Low(FObjects) to High(FObjects) do begin FObjects[i].Free(@FObjects[i]^); end;
SetLength(FObjects, 0); FNumObjects := 0; end; end;
Добавляются объекты в сцену так:
//Удаляем старый объект Scene.DeleteObject(@gObject);
//Создаем и загружаем файл LoadObj(OpenMeshDialog.FileName, RT, @ZCam, @gObject);
if gObject.Correct then begin Scene.AddObject(@gObject); Scene.SetObjectFirst(@gObject); end;
Потом сцена удаляется:
procedure TRenderForm.FreeScene; begin if bSceneActive then begin //Массив ссылок на Z-Объекты Scene.DestroyObjects;
//Объекты вне массива FreeAndNil(@gVarious); FreeAndNil(@gObject); FreeAndNil(@gGrid); FreeAndNil(@gFrustum);
//Кнопка загрузки FLoadBtn.Visible := False; FLoadBtn.Enable := False;
//Флаг использования 3D bSceneActive := false; end; end; Но мой вариант рабочий и вроде уже привык. Можно как то проще сделать? Буду рад услышать хорошие советы.
-
Мне nil понадобился, чтобы точно узнавать — инициализирован объект или нет. Если nil - то создаем в этой переменной или ячейке в массиве. У меня объекты динамически создаются/удаляются и какая переменная освободится заранее не известно. Вот здесь видно поведение объектов: https://yadi.sk/i/tU7G3tfHrl4hBQ
-
> Можно как то проще сделать? имхо конечно, но я как раз проще и посоветовал, работать со списком, стандартным. а не с массивом, и своим "велосипедом" по его обработке... ну, совсем без велосипеда не обойтись, но вот наследуй твой TZScene от TObjectList и у тебя сразу появятся стандартные методы по добавлению/удалению объектов, и "дестроить" их самому/следить за этим/за массивом не нужно будет, и т.д. много преимуществ/упрощений на мой взгляд. не, я конечно не совсем в теме, что у тебя там, со стороны не видно, вот к примеру зачем в 2-х местах ссылки? бери всегда из списка да и все. копию просто игнорь, в следующий раз если понадобится снова из списка, а nil-ов в нем попросту не будет, - стал не нужен объект, удалил из списка, а он уже сам его освободит... удобно.
-
>TObjectList Тут есть оговорка. VCL не используется. Почти чистый WinApi. Вплоть до своего менеджера памяти.
-
Какой феерический трындец.
> TObjectList > Тут есть оговорка. VCL не используется.
Можно посмотреть, как он реализован, не слишком сложная задача.
После просмотра этого:
>type > PZScene = ^TZScene; > TZScene = class
и этого:
>Вплоть до своего менеджера памяти.
у меня когнитивный диссонанс возникает.
Не дай бог такое приснится.
-
> pavia © (11.12.18 20:52) [39] > > > > прикольно, трупы сами себе могилу роют. > > в нормальных языках это давно так реализовано. > > > > возможно ли сделать так, чтобы объект при уничтожении сам > > себе присваивал nil? > > или надо freeandnil использовать? > > нельзя. > embarcodere уже который год тянут кота за яйца, но автосборку мусора сделать не могут. > да проще свой препроцессор написать. нормальный язык это где gc находит трупы и закапывает?
-
> Sha © (12.12.18 10:02) [51] > > > Германн © (12.12.18 02:21) [50] > > И GOTO, и FreeAndNil обычно не требуются программисту. > > Но в тех редких случаях, когда их применение действительно > имеет смысл, > они способны существенно упростить алгоритм или повысить > скорость.
Вот с этим я как раз и не спорил. Более того. У меня был случай, когда GOTO давал гораздо более понятный при просмотре/анализе/отладке код. А вот FreeAndNil никогда. Возможно потому, что у меня не достаточно было опыта.
|