![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
![]() Здравствуйте, у меня вопрос, с которым вот уже несколько дней не могу разобраться.
Переделал всё на максимально простой уровень, чтобы всем было понятно. Допустим у нас есть процедура: ---------- Случай 1 ---------- Код:
Procedure AddObject; var myObject:TButton; begin myObject:=TButton.Create(Form1); myObject.Caption:='Test Button'; myObject.Parent:=Form1; AddToList(myObject); // и т.п. end; может нужно как-то создать массив, в котором будут указатели(но у меня не получается) ![]() ---------- Случай 2 ---------- Если этот объект объявлен в глобальных переменных: Код:
var myObject:TButton; Ptr:^TButton; Код:
Procedure AddToList(var Obj:TButton); begin Ptr:=Addr(Obj); end; Procedure AddObject; begin myObject:=TButton.Create(Form1); myObject.Caption:='Test Button'; myObject.Parent:=Form1; AddToList(myObject); // и т.п. end; Procedure DeleteObj; begin FreeAndNil(Ptr^); end; ______________________ немного другой вопрос: ---------- Случай 3 ---------- допустим у нас это переменная глобальная: Код:
var myObject:TButton; Код:
var // глобальные переменные myObject:TButton; Ptr:array[1..100] of ^TButton; Count:Integer; Код:
Procedure AddToList(var Obj:TButton); begin Inc(Count); Ptr[Count]:=Addr(Obj); end; Procedure AddObject; begin myObject:=TButton.Create(Form1); myObject.Caption:='Test Button'+IntToStr(Random(1000)); myObject.Parent:=Form1; myObject.Left:=Random(100); MyObject.Top:=Random(50); AddToList(myObject); // и т.п. end; Procedure DeleteObj; var i:integer; begin For i:=1 to Count do FreeAndNil(Ptr[i]^); end; ![]() Если Вы находите ошибки, исправить которые дело долгое и нудное, ничего не делайте - просто внесите их в список особенностей ![]() Последний раз редактировалось Oleg, 17.08.2009 в 20:34. Причина: возник вопрос, который не дает покоя :( |
#2
|
||||
|
||||
![]() Сделал вот так:
Код:
var Ptr:array[1..100] of ^TButton; Count:Integer; //========================== Procedure AddToList(var Obj:TButton); begin Inc(Count); Ptr[Count]:=Addr(Obj); end; Procedure AddObject; var myObject:^TButton; begin new(myObject); myObject^:=TButton.Create(Form1); myObject^.Caption:='Test Button'+IntToStr(Random(1000)); myObject^.Parent:=Form1; myObject^.Left:=Random(100); MyObject^.Top:=Random(50); AddToList(myObject^); // и т.п. end; Procedure DeleteObj; var i:integer; begin For i:=1 to Count do FreeAndNil(Ptr[i]^); end; Код:
Procedure DeleteObj; var i:integer; begin For i:=1 to Count do IF Assigned(Ptr[i]) and Assigned(Ptr[i]^) then begin FreeAndNil(Ptr[i]^); Dispose(Ptr[i]); Ptr[i]:=nil; end; end; ![]() Если Вы находите ошибки, исправить которые дело долгое и нудное, ничего не делайте - просто внесите их в список особенностей ![]() Последний раз редактировалось Oleg, 17.08.2009 в 22:38. |
#3
|
||||
|
||||
![]() У всез компонентов есть своейство Components b и ComponentsCount;
Создай например глобальный объект ButtonOwner : TComponent; (не забудь создать в процедуре onCreate) Код:
Procedure AddObject; var myObject:TButton; begin myObject:=TButton.Create(ButtonOwner); myObject.Caption:='Test Button'; myObject.Parent:=Form1; // и т.п. end; Код:
if ButtonOwner.ComponentsCount <> 0 then ButtonOwner.Components[ButtonOwner.ComponentsCount - 1].Free; Но лучший вариант - воспользоваться списками TList или TObjList ...сказал, и загрустил от бесспорной своей правоты |
#4
|
||||
|
||||
![]() >> 0nni
так не пойдет, я кнопку взял лишь для примера, у меня свои классы другие. Если Вы находите ошибки, исправить которые дело долгое и нудное, ничего не делайте - просто внесите их в список особенностей ![]() |
#5
|
||||
|
||||
![]() Замени класс TButton на любой другой класс, в чем проблема?
...сказал, и загрустил от бесспорной своей правоты |
#6
|
||||
|
||||
![]() Сделай вот такие изменения и все будет работать с локальным объектом.
Код:
Ptr:array[1..100] of TButton; Ptr:TButton; Код:
Procedure AddToList(Obj:TButton); begin Ptr:=Obj end; Код:
Procedure DeleteObj; var i:integer; begin For i:=1 to Count do FreeAndNil(Ptr[i]); end; Вообще не мешало бы тебе почитать что есть указатель, что есть локальная переменная и почему указатель на него не рекомендутеся передавать, и что такое объект и почему указатель PObject = ^TObject - это глупо. ...сказал, и загрустил от бесспорной своей правоты |
#7
|
||||
|
||||
![]() Массив мне не подойдет, если бы он мне подходил, то я бы не задавал подобный вопрос.
>>"Вообще не мешало бы тебе почитать что есть указатель, что есть локальная переменная" всё это читал. >> "и почему указатель на него не рекомендутеся передавать" почему ? >> "и что такое объект и почему указатель PObject = ^TObject - это глупо." почему ? Если Вы находите ошибки, исправить которые дело долгое и нудное, ничего не делайте - просто внесите их в список особенностей ![]() Последний раз редактировалось Oleg, 18.08.2009 в 17:19. |
#8
|
|||
|
|||
![]() Есть класс TObjectList.
У него есть свойство - OwnObjects. Тогда достаточно просто удалить объект из этого класса и объект будет удален. Кнопка - для примера. Код:
type TForm1 = class(TForm) ... private FList : TObjectList; ... end; ... procedure TForm1.FromCreate(Sender : TObject); begin FList := TObjectList.Create(True); end; procedure TForm1.FromDestroy(Sender : TObject); begin FList.Free; end; procedure TForm1.CreateButton(ACaption : String); var AButton : TButton; begin AButton := TButton.Create(Nil); // !! Важно !! Если классы свои - то пофиг. AButton.Caption := ACaption; FList.Add(AButton); AButton.Parent := Self; // Это для визуальных контролов. Надо же ее показать :) end; // Удаляем по заголовку, просто пример. procedure TForm1.DeleteButton(ACaption : String); var I : Integer; begin For I := FList.Count-1 DownTo 0 Do If (Flist[i] As TButton).Caption = ACaption Then FList.Delete[i]; end; |
#9
|
||||
|
||||
![]() Цитата:
Код:
program Project3; {$APPTYPE CONSOLE} uses Windows; function GetPointerA : PInteger; var a : integer; begin a := 10; result := @a; end; var PointerA : PInteger; begin PointerA := GetPointerA; MessageBeep(0); Writeln(PointerA^); ReadLn; end. По поводу объектов - объект это и есть указатель. Код:
procedure SetButtonCaption(btn : TButton); begin btn.Caption := 'Hello world!'; begin; ...сказал, и загрустил от бесспорной своей правоты |
#10
|
||||
|
||||
![]() lmikle, спасибо конечно, но либо название класса неправильное(TObjectList), либо я не знаю в каком он модуле находится.
Этот класс тоже конечно полезный, но объясню как мне нужно в данный момент. Допустим у меня есть класс: Код:
TestClass = class public Ptr:^TButton; Constructor Create(var Obj:TButton); end; Constructor TestClass.Create(var Obj:TButton); begin Inherited Create; Ptr:=@Obj; end; кажется, если это глобальная переменная, то всё работает... А как быть, если это локальная ? ![]() Если Вы находите ошибки, исправить которые дело долгое и нудное, ничего не делайте - просто внесите их в список особенностей ![]() Последний раз редактировалось Oleg, 18.08.2009 в 19:19. |
#11
|
|||
|
|||
![]() Он в модуле Contnrs
Точно так же. Дело в том, что объект - уже указатель. Так что Ptr := @Obj должно быть Ptr := Obj. А память, выделяемая конструктором, никак не связана с тем, локльная это переменная или глобальная. Она просто выделена. Если создан объект в локальной переменной, и она выходит за область видимости, то ты получаешь утечку памяти, т.к. выделенная память не освобождается. Тут скорее вопрос, зечем тебе такая обертка? Я не иже в ней смысла. |
#12
|
||||
|
||||
![]() Проблема в том, что я программирую и пишу классы под 3D графику, есть свои классы объектов и т.п.
так вот, чтобы контролировать уничтожение объектов, я ввел такое свойство как Destroyng, как только это свойство истинно, то объект уничтожает другая класс, который контролирует все эти объекты, НО этот объект может использоваться и другими процедурами, классами и т.п., если не проверять существует ли этот объект или нет, то вылетает ошибка, т.к. что-то или кто-то пытается получить какие-то данные с объекта, которого уже нет ![]() Если Вы находите ошибки, исправить которые дело долгое и нудное, ничего не делайте - просто внесите их в список особенностей ![]() |
#13
|
||||
|
||||
![]() Код:
unit Unit1; interface type //базоый объект TMyCustomObject = class constructor Create; destructor Destroy; override; end; procedure Clear; function IsValidObject(Obj : TObject) : Boolean; implementation Uses Classes; var Objects : TList; procedure Clear; var i : Integer; begin for I := 0 to Objects.Count - 1 do TObject(Objects[0]).free; end; //функция проверки function IsValidObject(Obj : TObject) : Boolean; begin Result := Objects.IndexOf(Obj) <> -1; end; { TMyCustomObject } constructor TMyCustomObject.Create; begin Objects.Add(self); end; destructor TMyCustomObject.Destroy; var index : Integer; begin index := Objects.IndexOf(self); if index <> -1 then Objects.Delete(index); inherited; end; initialization Objects := TList.Create; finalization Clear; Objects.Free; end. ...сказал, и загрустил от бесспорной своей правоты |
#14
|
||||
|
||||
![]() Спасибо, 0nni, я уже пробовал через TList, но буду всё же использовать массивы, т.к. именно для данной задачи это будет более простым способом и надежным.
Спасибо за активность. Если Вы находите ошибки, исправить которые дело долгое и нудное, ничего не делайте - просто внесите их в список особенностей ![]() |