Область действия ЛП после добавления её в TList

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Аватара пользователя
Tango
постоялец
Сообщения: 162
Зарегистрирован: 31.05.2012 17:07:30

Область действия ЛП после добавления её в TList

Сообщение Tango »

Что будет с Локальной переменной и значением после такого кода?

Код: Выделить всё

function TLabels.CreateLabel(var Params: RLabelParams):TLabel;
var
  Leb:TLabel;
begin
  Leb:=TLabel.Create(FPanel);
  Leb.Parent:=FPanel;
  Leb.Left:=Params.LayoutParams.Left;
  Leb.Top:=Params.LayoutParams.Top;
....
  Leb.Caption:=Params.LabelText;
  FLabels.Add(TLabel(Leb));
end;


Куда денется память по выходу из функции, вроде как память под локальные переменные в стеке,
а он схлопнется. Никак не могу этого понять и найти ответ.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>вроде как память под локальные переменные в стеке
экземпляры классов всегда создаются в куче, Leb:TLabel - по сути просто указатель на кусок памяти в куче с данными класса. поэтому после отработки данного кода "схлопнется" только Leb, сам "класс" останется и будет доступен в FLabels и в соответствующих списках FPanel.
Это особенность классов, если тип Leb заменить на object или record то при создании экземпляра на стеке и выхода за его время жизни естественно будут проблемы
Аватара пользователя
Tango
постоялец
Сообщения: 162
Зарегистрирован: 31.05.2012 17:07:30

Сообщение Tango »

Всё понятно, спасибо.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3071
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

В таких случаях даже нет нужды в локальной переменной - можно писать так:

Код: Выделить всё

with TLabel.Create(FPanel) do
begin
...
end;
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Снег Север писал(а):В таких случаях даже нет нужды в локальной переменной - можно писать так:

сейчас будет холивар по поводу (не)использования with :)
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Снег Север
>>В таких случаях даже нет нужды в локальной переменной - можно писать так:
к сожалению тогда придется воттак:

Код: Выделить всё

with TLabel.Create(FPanel) do
begin
...
//FLabels.Add(Leb);
end;
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

скалогрыз писал(а):сейчас будет холивар по поводу (не)использования with :)

Ибо нефиг использовать эту конструкцию...
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 567
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

alexs писал(а):Ибо нефиг использовать эту конструкцию...


А чего в ней плохого?
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3071
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

zub писал(а):Снег Север
>>В таких случаях даже нет нужды в локальной переменной - можно писать так:
к сожалению тогда придется воттак:

Код: Выделить всё

with TLabel.Create(FPanel) do
begin
...
//FLabels.Add(Leb);
end;

А вот сакральный смысл занесения новорожденной в FLabels мне непонятен - она и так уже есть в FPanel.Components.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Снег Север
Всяко бывает, иногда приходится

alexs
>>Ибо нефиг использовать эту конструкцию...
+1 ))
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

WAYFARER, видимо то, что можно забыть, что переменная идет в сокращенной записи и попытаться так обратиться вне оператора with. По крайней мере, лично я именно поэтому перестал им пользоваться.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

WAYFARER писал(а):А чего в ней плохого?

Легко можно запутаться к полю какого объекта ты обращаешься.
Например:
Let есть у формы и у метки
при написании обработчика для формы
если укажешь

Код: Выделить всё

with Label1 ...
begin
... потом много текста
а тут Left:=1111
то как то не очевидно - чей этот Left
end

А вот Label1.Left - однозначно говорит о метке.
sts
энтузиаст
Сообщения: 549
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

запутаться ладно..., это мелочь, главная проблема with в том что изменение кода в совсем другом месте может привести к "мутации" кода в with, например

Код: Выделить всё

unit Unit1
...
procedure Test;
var
  a: string;
  b: TClass1;
begin
  with b do begin
     c := a;
  end;
end;
 
unit Unit2

  TClass1 = class
      с: string;
  end;


проходит время и мы добавляем в TClass1 поле a: string; и вуаля, все компилится но ошибка в коде - c := a;, "a" совсем другое

Добавлено спустя 3 минуты 17 секунд:
хотя лично я использую повсеместно и за 20 лет (ахренеть) тока пяток раз нарывался.

Добавлено спустя 4 минуты 31 секунду:
жаль в паскале нету особого "selfа" у процедуры, например так

Код: Выделить всё

procedure Test;
var
  a: string;
  b: TClass1;
begin
  with b, Test do begin
     c := a;
  end;
end;


это избавило бы от большинства проблем
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

sts писал(а):запутаться ладно..., это мелочь,

Нифига себе мелочь... сколько приходилось сидеть и втыкаться в текст... к тому же нередко встречается, что требуется скопировать данные между 2 и более таблиц или других компонент... тогда точно with нормально не используешь.
sts
энтузиаст
Сообщения: 549
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

по сравнению с указанной ситуацией - мелочь, так как ошибочность обнаруживается на этапе написания\отладки участка кода.
Ответить