Вопрос № 144768: hi... Есть ли в delphi хороший и удобный способ создания динамического массива? Перед мной стала задача создать динамический массив компонентов TEdit. Полистав немного справку, на меня уставилась функция SetLength() и вот что из этого вы...
Вопрос № 144.768
hi...
Есть ли в delphi хороший и удобный способ создания динамического массива? Перед мной стала задача создать динамический массив компонентов TEdit. Полистав немного справку, на меня уставилась функция SetLength() и вот что из этого вышло:
// очистка всех полей редактирования переданной формы от текста procedure clear_ed(form: TForm; eds_number: integer); var eds: array of TEdit; i: integer; begin SetLength(eds, eds_number); for i := 0 to form.Componentcount-1
do begin if(form.components[i] is TEdit) then begin eds[i]:= TEdit(form.components[i]); eds[i].Clear; end; end; end;
Однако, при повторном вызове этой функции, например кнопкой какой-нибудь - вылетает деббагер ( Еще немного полистав справку, нашелся GetMem(), от которого толку еще меньше... Неужели нет в delphi такой юзабильной функции как например в С++(new) или в С(malloc, calloc) ? Или что м
ожно сделать с кодом выше?
Отвечает: Кэр Лаэда
Здравствуйте, Maksim Trofimov!
а точно у вас она ругается только при повторном вызове ? посмотрите сами вы перебираете все компоненты на форме
for i := 0 to form.Componentcount-1 do
и если компонент is TEdit то вы что то делаете с компонентом т.е. ссылаетесь на какой то объект в массиве eds
и догадайтесь что происходит когда у вас на форме кроме TEdit есть например кнопка, следовательно вы выходите за диапазон массива eds.
вам нужно
делать так, так как у вас изначально известно что в массиве eds хранятся ссылки только на TEdit, значит вам не нужно перебирать все компоненты на форме а обращаться непосредственно к элементам массива .
Код:
for i := 0 to le
ngth(eds)-1 do begin eds[i].Clear; end;
--------- Я знаю что ничего не знаю, но я знаю больше, чем тот кто думает что знает все
Ответ отправил: Кэр Лаэда (статус: Практикант)
Ответ отправлен: 23.09.2008, 15:45 Оценка за ответ: 5 Комментарий оценки: да да да, все верно...поторопился с письмом на русфак. Ах, да! Перумов рулит!, Перумов рулит!...Yo ))
Отвечает: Лукьяненко Алексей Валериевич
Здравствуйте, Maksim Trofimov!
1) у вас дебаггер вылетает из-за неправильного использования массива. Вы выделяете eds_number элементов, а обращаетесь (записываетев массив) по индексу компонента. Вот и получается, что если Вы выделили место под 1 элемент, а на форма у Вас 3 компонента - то будет ошибка - обращение к несуществующему элементу при I = 2 к примеру. Индексы обращения к разным массивам должны быть разными. Правильно будет так:
var eds: array of TEdit; i, j: integer; begin SetLength(eds,
eds_number); J := 0; for i := 0 to form.Componentcount-1 do begin if form.components[i] is TEdit then begin eds[j]:= TEdit(form.components[i]); eds[j].Clear; Inc(j); end; end; end;
2) От GetMem толк есть. Если использовать тип PPointerArray (для Вашего примера):
var eds: PPointerArray; i, j: integer; begin eds := GetMem(eds_number * sizeof(TEdit)) J := 0; for i := 0 to form.Componentcoun
t-1 do begin if form.components[i] is TEdit then begin eds^[j]:= form.components[i]; TEdit(eds^[j]).Clear; Inc(j); end; end; end;
Ответ отправил: Лукьяненко Алексей Валериевич (статус: Студент)
Ответ отправлен: 23.09.2008, 15:46 Оценка за ответ: 5 Комментарий оценки: спасибо....так, так, так....а Вы случайно не родственник известному писателю )
Отвечает: Виктор Пырлик
Здравствуйте, Maksim Trofimov! Судя по названию — функция для очистки TEdit компонент.. Но тогда, массив создавать не к чему. Вот так, это может быть:
Код:
procedure clear_ed(form: TForm); var i: integer;
begin for i := 0 to form.Componentcount-1 do begin if (form.components[i] is TEdit) then (form.components[i] as TEdit).Clear; end ; end ; {$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); begin clear_ed(self); end ;
Во вторых – создание динамических массивов в Delphi подчиняется темже принципам что и в C/C++. Но вы работаете не с простыми типами а с классами. TEdit – это класс, потомок, далеко не первый, в дереве объектов. И для его инициализации надо использовать метод Create. Вот пример (в приложении) обоих процедур:
Приложение:
--------- Процесс обучения – cp -rfv /* /home/ - это рекурсия..:)
Ответ отправил: Виктор Пырлик (статус: Профессионал) Россия, Екатеринбург Тел.: 89043822027 ICQ: 490191733 ---- Ответ отправлен: 23.09.2008, 17:00 Оценка за ответ: 5 Комментарий оценки: Выходит, если мы работаем с классами, то всегда нужно явно использовать конструкторы create() ? ... и деструкторы destroy() для уничтожения? И вот это зачем:
Initialize(); Finalize(); ?