Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Динамический массив объектов. [D7, XP]


Страницы:   1 2

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

Здравствуйте, уважаемые Мастера.
У меня вот какой вопрос:
Имеется на форме 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' уже существует!
Объясните, пожалуйста, как правильно работать с динамическим массивом объектов?


Loginov Dmitry   (2007-02-05 09:25:00) [1]

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


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


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

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

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


Loginov Dmitry   (2007-02-05 08:09:00) [3]

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


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


Separator   (2007-02-05 08:08:00) [4]

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;


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

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

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


Джо   (2007-02-05 08:02:00) [6]

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

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


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

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


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

for i := Low() to High()


Loginov Dmitry   (2007-02-05 07:53:00) [8]

> 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 06:35:00) [9]


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

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


Джо   (2007-02-05 06:32:00) [10]

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

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


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

Выпил кофе и код принял такой вид:
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 05:57:00) [12]


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

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


Джо   (2007-02-05 05:53:00) [13]

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


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

По совету 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:38:00) [15]

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

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


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

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


Джо   (2007-02-05 05:28:00) [17]


> То есть так:

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


Джо   (2007-02-05 05:27:00) [18]


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

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


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

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


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

То есть так:

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


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

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

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо