![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамический массив объектов. [D7, XP]
Новичек © (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]);