Форум: "Начинающим";
Текущий архив: 2007.02.25;
Скачать: [xml.tar.bz2];
ВнизДинамический массив объектов. Найти похожие ветки
← →
Новичек © (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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.042 c