Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.25;
Скачать: CL | DM;

Вниз

Динамический массив объектов.   Найти похожие ветки 

 
Новичек ©   (2007-02-05 04:26) [0]

Здравствуйте, уважаемые Мастера.
У меня вот какой вопрос:
Имеется на форме Edit1, в него запихивается цифра. Затем на форме формируются панели в количестве, указанном в Edit1:

var
 pnlPanel: Array of TPanel;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 if Key <> vk_Return then exit;
 k := StrToInt(Edit1.Text);
 SetLength(pnlPanel, k);
 for i := 0 to k - 1 do
 begin
//Создание панели
   pnlPanel[i] := TPanel.Create(Form1);
   pnlPanel[i].Name := "pnlPanel" + IntToStr(i);
 end;
end;


Затем я меняю цифру в Edit1 и, соответственно, уничтожаю ранее созданный массив pnlPanel:

 SetLength(pnlPanel, 0);
 FreeAndNil(pnlPanel);


Запускаю вышеприведенную процедуру и получаю сообщение, что панель с именем "pnlPanel0" уже существует!
Объясните, пожалуйста, как правильно работать с динамическим массивом объектов?


 
Lex_! ©   (2007-02-05 04:32) [1]

pnlPanel[i].free
А массив ты даже не уничтожилд как таковой а просто прописал длинну 0 ..


 
Новичек ©   (2007-02-05 04:37) [2]


> А массив ты даже не уничтожилд как таковой а просто прописал
> длинну 0 ..

А FreeAndNil?

> pnlPanel[i].free

Пробовал вот так:
for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i]);
Не помогает :-(


 
ЮЮ ©   (2007-02-05 04:50) [3]


> for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i]);


в каком месте, интересно?
Неужели тружно шесть строк procedure TForm1.Edit1KeyDown повторить целиком с учетом исправлений?


 
Новичек ©   (2007-02-05 04:59) [4]


> в каком месте, интересно?


Вот в этом:
var
pnlPanel: Array of TPanel;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key <> vk_Return then exit;
for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i]);
k := StrToInt(Edit1.Text);
SetLength(pnlPanel, k);
for i := 0 to k - 1 do
begin
  pnlPanel[i] := TPanel.Create(Form1);
  pnlPanel[i].Name := "pnlPanel" + IntToStr(i);
end;
end;



> Неужели тружно шесть строк procedure TForm1.Edit1KeyDown
> повторить целиком с учетом исправлений?
>

Да ведь русским же языком сказал - НЕ РАБОТАЕТ. Объекты pnlPanel[i] не уничтожаются, а посему вновь создаваемому объекту невозможно присвоить то же имя, что было до исправления.


 
Новичек ©   (2007-02-05 05:11) [5]

Причем, вот что интересно: ежели массив сделать статическим, то все проблемы исчезают.
Юрий Юрьевич, у Вас богатый опыт - где грабли?


 
Джо ©   (2007-02-05 05:11) [6]

Господи, ну неужели сложно просто вдумчиво прочитать ответы? Объекты нужно уничтожать. Объекты уничтожаются вызовом метода Free. А ты просто затираешь содержимое массива, в котором у тебя храняться ссылки на эти объекты.


 
Новичек ©   (2007-02-05 05:15) [7]


> Господи, ну неужели сложно просто вдумчиво прочитать ответы?
>  


Вызов FreeAndNil как раз и вызывает метод Free.


 
Джо ©   (2007-02-05 05:19) [8]


> Вызов FreeAndNil как раз и вызывает метод Free.

Давайте Вы мне не будете ничего доказывать, а я не буду комментировать Ваш код:
FreeAndNil(pnlPanel);
ОК? :)


 
Новичек ©   (2007-02-05 05:22) [9]

Давайте.
Только мой код выглядит несколько иначе:

> for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i]);


 
Новичек ©   (2007-02-05 05:23) [10]

То есть так:

for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i]);


 
Джо ©   (2007-02-05 05:27) [11]


> Новичек ©   (05.02.07 05:22) [9]
> Давайте.Только мой код выглядит несколько иначе:

Гм. А это чей пост:


> Затем я меняю цифру в Edit1 и, соответственно, уничтожаю
> ранее созданный массив pnlPanel:
>
>  SetLength(pnlPanel, 0);
>  FreeAndNil(pnlPanel);

Или Вы полагаете, что у каждого должно хватать терпения читать каждый Ваш пост, в котором код тасуется так же шустро, как и карты в руках Копперфильда?


 
Джо ©   (2007-02-05 05:28) [12]


> То есть так:

И сколько будет этих «то есть» еще?


 
Новичек ©   (2007-02-05 05:30) [13]

Джо: Вы что, не с той ноги встали? Грубите, пожалуйста, своим друзьям.


 
Джо ©   (2007-02-05 05:38) [14]

> [13] Новичек ©   (05.02.07 05:30)
> Джо: Вы что, не с той ноги встали? Грубите, пожалуйста,
> своим друзьям.

Мне сейчас совершенно не интересно обсуждать моральные аспекты в тематической конференции, поэтому я и не буду. Просто для удобства тех, кто посчитает нужным тут отвечать, приведите, пожалуйста, ОКОНЧАТЕЛЬНЫЙ код, по поводу которого Вы хотели бы получить совет и комментарии специалистов.


 
Новичек ©   (2007-02-05 05:46) [15]

По совету Lex"a код принял такой вид:
var
pnlPanel: Array of TPanel;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
 if Key <> vk_Return then exit;
 for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i]);
 FreeAndNil(pnlPanel);
 k := StrToInt(Edit1.Text);
 SetLength(pnlPanel, k);
 for i := 0 to k - 1 do
 begin
   pnlPanel[i] := TPanel.Create(Form1);
   pnlPanel[i].Name := "pnlPanel" + IntToStr(i);
 end;
end;


 
Джо ©   (2007-02-05 05:53) [16]

Не придираясь к частностям,
FreeAndNil(pnlPanel);
— лишнее.


 
Новичек ©   (2007-02-05 05:57) [17]


> Не придираясь к частностям,
> FreeAndNil(pnlPanel);
> — лишнее.
>

Согласен. Это я в отчаянии написал.


 
Новичек ©   (2007-02-05 06:15) [18]

Выпил кофе и код принял такой вид:
var
pnlPanel: Array of TPanel;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
 if Key <> vk_Return then exit;
 if Assigned(pnlPanel) then
 for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i]);
 k := StrToInt(Edit1.Text);
 SetLength(pnlPanel, k);
 for i := 0 to k - 1 do
 begin
   pnlPanel[i] := TPanel.Create(Form1);
   pnlPanel[i].Name := "pnlPanel" + IntToStr(i);
 end;
end;

Теперь все работает. Стало быть, вызов FreeAndNil(pnlPanel) вызывал исключение (спасибо Джо, приношу извинения, если был невежлив).
Но почему этот вызов не уничтожает элементы массива?!!! Ведь массива-то нет.


 
Джо ©   (2007-02-05 06:32) [19]

> Стало быть, вызов FreeAndNil(pnlPanel) вызывал исключение

Метод Free, по определению, есть только у объектов. В Delphi массив — НЕ объект.


 
Новичек ©   (2007-02-05 06:35) [20]


> В Delphi массив — НЕ объект.

Ну, конечно же!!! Посыпаю голову пеплом :-(
Значит, пора спать :-)


 
Loginov Dmitry ©   (2007-02-05 07:53) [21]

> for i := 0 to k-1 do if Assigned(pnCell[i]) then FreeAndNil(pnCell[i])
> ;


if Assigned(pnCell[i]) можно удалить, оно и так при вызове FreeAndNil() проверится.

>
> if Assigned(pnlPanel) then


Это для кого?


> for i := 0 to k-1 do


Правильнее так:
for i := 0 to High()

Только ниасилил выбрать, чтоже всетаки написать внутри High().

В 10-х: нафига панелькам имя присваиваешь? Лишнее оно. Ведь ссылки же итак находятся в каком то из массивов (pnlPanel или pnCell - (выбирай)). А имена нужны в основном только при работе с контролами в дизайнере.

Вот видишь, сколько ляпов может быть в таком простом коде. Здесь их раза в два больше, чем полезного кода.


 
Думкин ©   (2007-02-05 07:58) [22]

> Loginov Dmitry ©   (05.02.07 07:53) [21]
> Правильнее так:
> for i := 0 to High()


Ежели вовсе по взрослому, то

for i := Low() to High()


 
Джо ©   (2007-02-05 08:02) [23]

> [22] Думкин ©   (05.02.07 07:58)
> Ежели вовсе по взрослому, то

Ежели «по-взрослому», то от кода и подхода в [18] можно оставлять только рожки да ножки, но это дело такое :)


 
Думкин ©   (2007-02-05 08:06) [24]

> Джо ©   (05.02.07 08:02) [23]

Оно понятно. Но можно быть взрослым вообще и можно в частностях. :)


 
Separator ©   (2007-02-05 08:08) [25]

var
pnlPanel: Array of TPanel;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key <> vk_Return then exit;
if Assigned(pnlPanel) then
  for i:= Low(pnlPanel) to High(pnlPanel) do
    FreeAndNil(pnlPanel[i]);
k:= StrToInt(Edit1.Text);
SetLength(pnlPanel, k);
for i:= Low(pnlPanel) to High(pnlPanel) do
  pnlPanel[i]:= TPanel.Create(Form1);
end;


 
Loginov Dmitry ©   (2007-02-05 08:09) [26]

> Ежели вовсе по взрослому, то
>
> for i := Low() to High()


А вот это для динамических массивов уже совсем лишнее. Лично для себя я всегда предпочитаю 0 вместо Low.


 
Думкин ©   (2007-02-05 08:17) [27]

> Loginov Dmitry ©   (05.02.07 08:09) [26]

Спорить тут - религия уже. :)
Понятно что always from zero for dynamic arrays. Но дело внутреннее.


 
Loginov Dmitry ©   (2007-02-05 09:25) [28]

> if Assigned(pnlPanel) then
>  for i:= Low(pnlPanel) to High(pnlPanel) do


Опять... Зачем здесь Assigned(pnlPanel)?



Страницы: 1 вся ветка

Текущий архив: 2007.02.25;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.05 c
2-1170941650
niil
2007-02-08 16:34
2007.02.25
Загрузка картинки в Image из интернета


1-1167240571
Чапаев
2006-12-27 20:29
2007.02.25
Затормозить мышку


2-1170879979
niil
2007-02-07 23:26
2007.02.25
Событие onMouseDown для создаваемого в ран-тайме TTabSheet


4-1160568526
ga3
2006-10-11 16:08
2007.02.25
как скрыть окно вызывающего процесса из dll?


15-1170244018
пластилин глазами хакера
2007-01-31 14:46
2007.02.25
Антивирус