Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Создание-удаление диалога


Страницы:   1 2 3

lookin ©   (2007-12-19 21:43:00) 

Вопрос - нижеследующий блок №1 ошибочен, и если да, то чем? Вызывает AV в ряде случаев...

*****№1 Начало
procedure CreateFontDialog(var AFontDialog: TFontDialog; AOwner: TComponent);
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;
*****№1 Конец

И второй блок, не вызывает AV. Почему?

*****№2 Начало
procedure CreateFontDialog(var AFontDialog: TFontDialog; AOwner: TComponent);
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;
*****№2 Конец

И завершающий вопрос - что правильнее? Спасибо!


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]
>
>
> > Старею, да и уже вторую неделю левое колено почти не сгибается.
>
> >  :)
>
> Ну не коленом же буквы набиваешь! :)
>

А ты пробовал "набивать буквы лёжа"?
:)


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо