![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание-удаление диалога
lookin © (2007-12-19 21:43:00)Вопрос - нижеследующий блок №1 ошибочен, и если да, то чем? Вызывает AV в ряде случаев...
*****№1 Начало
procedure CreateFontDialog(var AFontDialog: TFontDialog; AOwner: TComponent);*****№1 Конец
begin
if not Assigned(AFontDialog) then
AFontDialog:=TFontDialog.Create(AOwner);
end;
procedure DestroyFontDialog(var AFontDialog: TFontDialog);
begin
if Assigned(AFontDialog) then AFontDialog.Free;
end;
****Вызов создания-удаления диалога TFontDialog****
procedure TEqapSurfaceChart.ChartTitleFontButtonClick(Sender: TObject);
var FontDialog: TFontDialog;
begin
CreateFontDialog(FontDialog,nil);
if FontDialog.Execute then begin
...
end;
DestroyFontDialog(FontDialog);
end;
И второй блок, не вызывает AV. Почему?
*****№2 Начало
procedure CreateFontDialog(var AFontDialog: TFontDialog; AOwner: TComponent);*****№2 Конец
begin
AFontDialog:=nil;
AFontDialog:=TFontDialog.Create(AOwner);
end;
procedure DestroyFontDialog(var AFontDialog: TFontDialog);
begin
if Assigned(AFontDialog) then AFontDialog.Free;
end;
****Вызов создания-удаления диалога TFontDialog****
procedure TEqapSurfaceChart.ChartTitleFontButtonClick(Sender: TObject);
var FontDialog: TFontDialog;
begin
CreateFontDialog(FontDialog,nil);
if FontDialog.Execute then begin
...
end;
DestroyFontDialog(FontDialog);
end;
И завершающий вопрос - что правильнее? Спасибо!
han_malign (2007-12-21 16:35:00) [1]
> Мне б что конструктивное...
>
var FontDialog: TFontDialog;
begin
CreateFontDialog(FontDialog,nil);
- объясняю на пальцах
1.var FontDialog: TFontDialog;- означает что указатель СТЕКА! смещается на четыре байта, резервируя место под переменную на СТЕКЕ!.
2. Стек по выходу из процедур никто не чистит, т.к. попытки вручную очистить локальные переменные при выходе проигнорирует оптимизатор, а процессорная инструкция ret - по определению, только сдвигает указатель стека назад и переходит в точку возврата, по адресу из текущей ячеки.
Итак мы выяснили: 1. переменная выделяется на стеке; 2. в стеке лежат остатки жизнедеятельности предыдущих процедур.
Вопрос: чему равно значение указателя на экземляр класса - FontDialog?
Ответ: если очень сильно повезет то нулю, но лучше, все таки, если не повезет сразу - ошибка отловится на этапе отладки...
БИБЛИЯ: ВСЕ (локальные) переменные надо ИНИЦИАЛИЗИРОВАТЬ!
В данном конкретном случае это должно выглядеть так:
var FontDialog: TFontDialog;
begin
FontDialog:= nil;
CreateFontDialog(FontDialog,nil);
...
З.Ы. Длинные строки и динамические массивы - инициализируются compiler magic(в том числе в локалных структурах, массивах и массивах структур), но лучше, даже в этом случае, не привыкать к халяве и инициализировать все явно...
Loginov Dmitry (2007-12-20 07:40:00) [2]> Foo::GetInstance()::PrintA(); // a = 0 - обьект класса Foo
> создается тут, в GetInstance
> Foo::GetInstance()::PrintA(); // a = 1 - а тут он просто
> продолжает жить
>
>
> Элегантно. (Грабли впрочем тут есть, не спорю...)
В Delphi также можно. Но особого применения {$J+} не получило (этож целых 4 буквы в модуле дополнительно набивать нужно! )))
Loginov Dmitry (2007-12-20 07:35:00) [3]> Похоже разработчики Борланда оказали дурную услугу пользователям
> Дельфи введя в язык функцию Assigned(). Реально, имхо, она
> никому не нужна кроме разработчиков компонент.
Реально может и не нужна, но все ею пользуются. Удобно при проверке переменных процедурного типа. Запись
if Assigned(Proc1) and Assigned(Proc2)
выглядет элегантнее, чем
if (@Proc1 <> nil) and (@Proc2 <> nil)
хотя по числу букв - одно и то же )))
Германн (2007-12-20 04:18:00) [4]
> lookin © (20.12.07 04:11) [45]
>
> > [44] Германн © (20.12.07 04:09)
>
> Ага, спасибо. Просто нефиг советовать того, что сам не пробовал
> (таджикская мудрость)...
> <Цитата>
>
> lookin © (20.12.07 04:13) [46]
>
> Мне б что конструктивное...
>
Уймись, ради бога!
Ведь когда утром проснутся все прочие форумчане, от тебя не оставят ничего. Придётся менять ник или продолжать позорное существование.
lookin (2007-12-20 04:13:00) [5]Мне б что конструктивное...
lookin (2007-12-20 04:11:00) [6]> [44] Германн © (20.12.07 04:09)
Ага, спасибо. Просто нефиг советовать того, что сам не пробовал (таджикская мудрость)...
Германн (2007-12-20 04:09:00) [7]
> > [41] Германн © (20.12.07 03:54)
>
> Да как бы ни хрена ты не пояснил... Без обид, мальчик...
>
>
Ну тогда читай книги, старичок. Вот только сумлеваюсь что ты сможешь на смертном одре сказать "Дык я всё-таки хоть что-то понял в Дельфи/Паскале"!
Без обид, Олежка.
lookin (2007-12-20 04:03:00) [8]Удалено модератором
Примечание: Следи за речью
lookin (2007-12-20 04:01:00) [9]Удалено модератором
Германн (2007-12-20 03:54:00) [10]
> lookin © (20.12.07 03:37) [34]
>
> > [25] Германн © (20.12.07 01:43)
>
> Я понимаю под локальной переменной ту, которая срабатывает
> только при входе в некоторую процедуру-функцию. Нет?
>
Правильно понимаешь.
> lookin © (20.12.07 03:39) [35]
>
> > [25] Германн © (20.12.07 01:43)
>
> а Assigned(***) "Tests for a nil (unassigned) pointer or
> procedural variable".
А Assigned проверяет переменную-параметр на 0 (nil). А как уже было сказано Делфи не обнуляет локальные переменные по-умолчанию. (И тут нигде и ни как не проверяется на что указывает сия переменная.)
> lookin © (20.12.07 03:40) [36]
>
> > [33] Германн © (20.12.07 02:49)
>
> не спорю насчет твоей справедливости, только поясни плз
>
Надеюсь пояснил. Или есть ещё вопросы?
> lookin © (20.12.07 03:41) [37]
>
> > [33] Германн © (20.12.07 02:49)
>
> Просто казалось бы, разницы между if not Assigned(Dlg) и
> Dlg:=nil нету... Нету?
>
Де-факто нет никакой разницы. Де-юре есть. См. Германн © (20.12.07 01:55) [26]
J_f_S (2007-12-20 03:49:00) [11]А, блин. Очипятки в [38]. Но смысл понятен.
J_f_S (2007-12-20 03:46:00) [12]Действительно ли это для Делфей, впрочем, сказать не могу :)
Наверно, нет.
J_f_S (2007-12-20 03:44:00) [13]Если локальная переменная обьявлена с модификатором static, то она не уничтожается при выходе за область своего действия. На этом основан принцип работы синглтона Майерса:
class Foo
{
private:
~Foo();
Foo(const Foo&){};
Foo():a(0);
int a;
public:
static Foo& GetInstance();
void PrintA();
}
///cpp
Foo& Foo::GetInstance()
{
static Foo fooInstance;
return fooInstance;
}
void Foo::PrintA()
{
printf("a = %d", a++);
}
Foo::GetInstance()::PrintA(); // a = 0 - обьект класса Foo создается тут, в GetInstance
Foo::GetInstance()::PrintA(); // a = 1 - а тут он просто продолжает жить
Элегантно. (Грабли впрочем тут есть, не спорю...)
lookin (2007-12-20 03:41:00) [14]> [33] Германн © (20.12.07 02:49)
Просто казалось бы, разницы между if not Assigned(Dlg) и Dlg:=nil нету... Нету?
lookin (2007-12-20 03:40:00) [15]> [33] Германн © (20.12.07 02:49)
не спорю насчет твоей справедливости, только поясни плз
lookin (2007-12-20 03:39:00) [16]> [25] Германн © (20.12.07 01:43)
а Assigned(***) "Tests for a nil (unassigned) pointer or procedural variable". При чем тут несоотвествие моего кода №1?
lookin (2007-12-20 03:37:00) [17]> [25] Германн © (20.12.07 01:43)
Я понимаю под локальной переменной ту, которая срабатывает только при входе в некоторую процедуру-функцию. Нет?
Германн (2007-12-20 02:49:00) [18]И ещё раз, как бы ни старались представители СИ сбить нас с толку.
Германн © (20.12.07 01:55) [26]
Германн (2007-12-20 02:39:00) [19]Не хочу сейчас флудить. Объясни на русском суть твоего сообщения:
> J_f_S (20.12.07 02:24) [27]
>
>
> > Локальные переменные не могут "уже" существовать
>
> В С - могут :)
>
Германн (2007-12-20 02:37:00) [20]
> J_f_S (20.12.07 02:33) [29]
>
>
> > Старею, да и уже вторую неделю левое колено почти не сгибается.
>
> > :)
>
> Ну не коленом же буквы набиваешь! :)
>
А ты пробовал "набивать буквы лёжа"?
:)