Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.02.17;
Скачать: [xml.tar.bz2];

Вниз

Создание класса   Найти похожие ветки 

 
Grinder   (2004-02-06 19:52) [0]

Ребята, помогите.

Почему переменная объявленная в var ещё до создания при вызове Assigned(myvar) = true?

...
var
myvar:TMyType;
begin
if Assigned(myvar) then
beep; // До сюда доходит!!! Но Create нету
...

Т.е. я не сделал ещё myvar:=TMyType.Create; А она уже Assigned? Класс ни от чего не наследован (т.е. сразу от Tobject).

type TMyType = class
...

Вот конструктор

...
constructor Create;

end;

implementation

constructor TMyType.Create;
begin
inherited Create;
FStop:=False;
Timer:=TTimer.Create(Application);
Timer.Enabled:=False;
Timer.Interval:=1000;
TImer.OnTimer:=OnTimer;
FTag:=0;
end;

...

Буду рад пояснениям.


 
Юрий Зотов   (2004-02-06 19:54) [1]

Assigned всего лишь проверяет на nil. Если переменная не была инициализирована, то в ней может сидеть любой мусор. Вот Assigned и дает True.


 
Cobalt   (2004-02-06 20:32) [2]

Стек при выделении под локальные переменные не очищается - конечно, дурная привычка. Но, кто знает, что в этом стеке лежит...


 
Тимохов   (2004-02-06 20:43) [3]


Cobalt © (06.02.04 20:32) [2]
> Стек при выделении под локальные переменные не очищается

Разрешите поправку?
Под некоторые очищается.
Например под:
1. длинные строки (точно)
2. дин. массивы (не уверен, правда)
3. интерфейсы (точно)


 
Sergey_Masloff   (2004-02-06 21:00) [4]

Тимохов © (06.02.04 20:43) [3]
под все ссылочные очищается.


 
Тимохов   (2004-02-06 21:05) [5]


> Тимохов © (06.02.04 20:43) [3]
> под все ссылочные очищается.

Наверное, но не понятно почему тогда комипилятор выдает предупреждение на строку d := d1, а на строку s := s1 - нет

procedure TForm1.Button6Click(Sender: TObject);
var
s,s1: string;
d,d1: array of integer;
begin
s := s1;
d := d1;
end;


 
Sergey_Masloff   (2004-02-06 22:57) [6]

Да, наврал я...
Local variables, in contrast, cannot be initialized in their declarations and contain random data until a value is assigned to them.


 
Grinder   (2004-02-07 00:10) [7]

Ребята, вот я объявляю переменную типа TStringList.
Не создаю ничего. Вызываю assigned. False. Почему тогда у меня True?


 
Grinder   (2004-02-07 00:42) [8]

Упс. Извиняюсь. Я просто вызвал до этого stringlist:=nil ^:)Но другой вопрос. Моечму когда я переменной MyType:=nil делаю компилятор эту строку игнорирует?


 
Grinder   (2004-02-07 12:06) [9]

В общем как сделать, чтобы переменная могла быть nil?

И ещё. Если переменная без создания Create имеет какое-то значение, почему нельзя ей сделать free?


 
Юрий Федоров   (2004-02-07 12:14) [10]

все локальные переменные находятся в стеке
там мусор
зачем делаьб ей free ?
если это указатель на объект - он указывает в случайное место памяти до того, как его инициализировали
если надо, чтобы "переменная могла быть nil" - присвой ей nil
Это касается локальных переменных
глобальные автоматически инициализируются нулями


 
Grinder   (2004-02-07 16:10) [11]

Мне надо чтобы было nil, но проблема в том, что компилятор эту строку игноритует нагло! Переменная локальная.


 
Digitman   (2004-02-07 16:20) [12]


> компилятор эту строку игноритует нагло


отключи в опциях проекта оптимизацию, не будет игнорировать
а если при включенной оптимизации игнорирует, это означает что лок.переменная не используется в коде п/программы


 
Никто   (2004-02-07 16:22) [13]

{$OPTIMIZATION OFF}
MyVar := nil;
{$OPTIMIZATION ON}

или

const
MyVar: TMyType = nil;


 
Никто   (2004-02-07 16:25) [14]

const (!!!)
переработался...


 
Никто   (2004-02-07 16:31) [15]

Да нет, все правильно было! Не переработался.


 
Grinder   (2004-02-07 16:44) [16]

Всё равно игнорирует. Может кто посоветует как поступить.
Вот смотрите.

procedure Tform.Loading;
var
i:cardinal;
ini:TIniFile;
stringlist:TStringList;
loadedalarm:TAlarm; // Вот мой класс
begin
{$OPTIMIZATION OFF}
loadedalarm:=nil; // Тут полное игнорирование
{$OPTIMIZATION ON}
ini:=TIniFile.Create(ExtractFilePath(progpath)+"files.dat");
stringlist:=TStringList.Create;
loadedalarm:=TAlarm.Create;
try
ini.ReadSections(stringlist);
ListBox1.Items.Assign(stringlist);
if stringlist.Count>0 then
for i := 0 to stringlist.Count-1 do begin

loadedalarm.Tag:=ini.ReadInteger(stringlist[i],"tag",0);
LoadAlarms(loadedalarm);
loadedalarm.Start;
loadedalarm.OnAlarm:=Button2.OnClick;
alarmlist.Add(loadedalarm);
//
end;
finally
ini.Free;
stringlist.Free;
// loadedalarm.free;
end;
end;

Вот кусок кода

alarmlist:Tlist.

Что делаю теперь.

procedure Tform.Button2Click(Sender: TObject);
begin
beep;
MessageBox(application.handle,PChar((Sender as TAlarm).messagetext),"",MB_OK);
end;

Так всё работает. Но как видите в первом коде я не делаю loadedalarm.free;, потому что тогда во втором коде Sender as TAlarm не определено почему-то. Я никак не могу понять почему. Какое отношение локальная переменная loadedalarm имеет к обработчику события? Ведь я её добавил уже в Tlist и она там должна быть и инициализироваться. Просто когда я делаю alarmlist.clear, то по идее всё из него должно удаляться, но почему-то последняя перменная, которая в нем находится остается в работе. Видимо потому что я не ощищаю в первом коде loadedalarm.free. Так как мне его очестить так, чтобы Sender as TAlarm во втором коде не вызывал Access Violation?


 
Digitman   (2004-02-07 17:06) [17]

какой тип имеет ид-р alarmlist ?


 
jack128   (2004-02-07 17:10) [18]


> begin
> {$OPTIMIZATION OFF}
> loadedalarm:=nil; // Тут полное игнорирование
> {$OPTIMIZATION ON}
> ini:=TIniFile.Create(ExtractFilePath(progpath)+"files.dat");
> stringlist:=TStringList.Create

....

Из хелпа
Note: The $O directive can only turn optimization on or off for an entire procedure or function. You can’t turn optimization on or off for a single line or group of lines within a routine.


 
Grinder   (2004-02-07 17:32) [19]

2 Digitman

Tlist. Хотя пробовал и TobjectList, но сути это не изменило.


 
Digitman   (2004-02-07 17:41) [20]


> Grinder © (07.02.04 17:32) [19]


метод Tlist.Clear уничтожает список указателей (в твоем случае - на объеты класса TAlarm) , но не уничтожает сами объекты .. т.е. если указатель на существующий объект существует только в этом списке (и более нигде), то после удаления указателя в методе Clear объект будет потерян в памяти

TobjectList.Clear же, кроме уничтожения списка указателей, для каждого указателя пытается интерпретировать его как указательна объект и вызвать его метод Free ... если указатель действителен (т.е. указавает на существующий объект), то объект будет разрушен, после чего указатель уничтожен ... если в программе где-то в ином месте существует еще один указатель на этот объект, то отныне он будет указывать в никуда (т.е. - "мусор"), и попытка вызова другой_указатель.Free приведет к AV


 
Digitman   (2004-02-07 17:48) [21]

иными словами, если объект уничтожается в том или ином месте программы, то необходимо принять те или иные программные меры, чтобы все прочие (возможно существующие) указатели на тот же самый объект были после его уничтожения обнулены (т.е. отныне = nil)

потеря же объекта в памяти - другой конец той же палки : если ты уничтожишь или присвоишь nil всем существующим указателям на данный объект, то его действ.адрес в памяти будет практически безвозвратно утерян, и уничтожить объект, не зная его адреса, практически не представляется возможным (либо это чрезвычайно сложно и не оправдано с т.з. нормально работающего и отлаженного алгоритма)


 
Digitman   (2004-02-07 17:58) [22]

поскольку loadedalarm - локальная переменная (являющая собой указатель на объект), то время жизни ее = времени работы п/программы

предположим, ты создал в п/программе объект и занес указатель на него в лок.переменную

loadedalarm:=TAlarm.Create;

выполняя в п/программе строчку
alarmlist.Add(loadedalarm);
ты делаешь копию указателя на объект и заносишь эту копию в список ... отныне переменная loadedalarm не нужна - объект существует и ссылка на него хранится в некоем списке. время жизни которого = времени жизни программы в целом

в неуий момент времени тебе потребовалось разрушить объекты. ссылки на которые хранятся в списке

если список типа TObjectList, достаточно просто вызвать его метод Clear

если же тип списка TList, то перед вызовом метода Clear ты должен в цикле пройтись по всем эл-там списка, и для каждого из них вызвать TAlarm(alarmlist[i]).Free


 
Grinder   (2004-02-07 18:22) [23]

OK
буду копаться.




Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.02.17;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.014 c
1-53472
xz-man
2004-02-06 04:06
2004.02.17
Mdi-forms


1-53623
griff
2004-02-09 15:10
2004.02.17
Список функций в DLL, использующих конкретную функцию


4-53807
Thick
2003-12-12 13:38
2004.02.17
Не могу выключить прогу


6-53672
MaG
2003-12-12 18:07
2004.02.17
Скачивание файлов


1-53535
[lamer]Barmaglot
2004-02-09 09:10
2004.02.17
Построение автомата...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский