Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.52 MB
Время: 0.042 c
4-1161004753
Джо
2006-10-16 17:19
2007.02.25
GetClipboardData(CF_BITMAP) и GlobalLock


15-1170238059
hmmm
2007-01-31 13:07
2007.02.25
PHP, алиасы


15-1170235098
RustamK
2007-01-31 12:18
2007.02.25
Трансляция ТВ


2-1170682880
Legolas
2007-02-05 16:41
2007.02.25
Чтение файла


15-1170419959
Observer
2007-02-02 15:39
2007.02.25
Загрузка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский