Форум: "Основная";
Текущий архив: 2008.09.07;
Скачать: [xml.tar.bz2];
ВнизСоздание-удаление диалога Найти похожие ветки
← →
lookin © (2007-12-19 21:43) [0]Вопрос - нижеследующий блок №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;
И завершающий вопрос - что правильнее? Спасибо!
← →
Petr V. Abramov © (2007-12-19 21:48) [1]а где AV?
← →
Германн © (2007-12-19 21:48) [2]
> AFontDialog:=nil;
> AFontDialog:=TFontDialog.Create(AOwner);
>
И ЭТО не вызывает AV? Не смеши мои тапочки.
← →
Германн © (2007-12-19 21:50) [3]
> Германн © (19.12.07 21:48) [2]
>
>
Не читать. Не туда посмотрел.
> lookin © (19.12.07 21:43)
Прочитай справку по функции Assigned.
← →
Loginov Dmitry © (2007-12-19 21:53) [4]> что правильнее?
FreeAndNil()
← →
lookin © (2007-12-19 22:27) [5]> [3] Германн © (19.12.07 21:50)
Да читал, толку что-то маловато от меня. Прояснишь? Мне то казалось, что создавая экземпляр, я могу его и убивать (процедуры Create*** и Destroy***). А вот что-то не получается. Создавать. AV возникает на вызов CreateFontDialog, при еще ни разу не созданном (еще бы, в локальной перемнной все же) диалоге. И не знаю, почему такая загвоздка...
← →
{RASkov} © (2007-12-19 22:44) [6]> [5] lookin © (19.12.07 22:27)
> Да читал, толку что-то маловато от меня. Прояснишь?
Просто нужно помнить, что Free не обну(и)ляет ссылку.... и все встает на свои места....
т.е. после Free - Assigned "думает", что объект-то жив, а его на самом деле уже нет вот и АВ
или см [4]
или "мочи" объекты так:
Obj.Free;
Obj:=nil;
← →
Sergey Masloff (2007-12-19 22:52) [7]Правильно так
with TFontDialog.Create(AOwner) do
try
if Execute then
finally
Free();
end;
- нет лишних переменных
- не надо никаких assigned
- можно спокойно забыть про freeandnil которая по самой сввоей идее опасна
← →
Petr V. Abramov © (2007-12-19 22:56) [8]> freeandnil которая по самой сввоей идее опасна
не так у ж и опасна. на AV нарвешься при обращении к фрееэндобнилиномму объекту, а не в произвольном месте.
← →
lookin © (2007-12-19 23:03) [9]> [6] {RASkov} © (19.12.07 22:44)
Гут, спасибо. Но как насчет того, что AV возникает при ПЕРВОМ вызове процедуры создания диалога (при работе с №1). Т.е. объекта то и в помине нету, казалось бы. Правда осекусь, речь идет о вызове искомой после создания динамически компонента, использующего эти перечисленные выше процедуры, возможно, это является решающим. Так как в обычном приложении такого AV не возникает...
← →
lookin © (2007-12-19 23:04) [10]> [7] Sergey Masloff (19.12.07 22:52)
Понятна мысль, но мне в каждой процедуре писать такое? Я ведь потому и создал "шаблонный" вызов, чтобы не повторяться...
← →
{RASkov} © (2007-12-19 23:25) [11]> [9] lookin © (19.12.07 23:03)
> Но как насчет того, что AV возникает при ПЕРВОМ вызове процедуры
> создания диалога (при работе с №1).
Первый вариант один раз должен отработать нормально, т.е. до первого Free а последующие разы АВ....
> Понятна мысль, но мне в каждой процедуре писать такое? Я
> ведь потому и создал "шаблонный" вызов, чтобы не повторяться...
У тебя шаблоны написаны не верно....
Вот посмотри вариант:type TCommonDialogClass = class of TCommonDialog;
function ExecDlg(const TDlg: TCommonDialogClass; AOwner: TComponent=nil): Boolean;
begin
with TDlg.Create(AOwner) do try
Result:=Execute;
finally
Free;
end;
end;
..................
begin
ExecDlg(TFontDialog);
ExecDlg(TColorDialog);
ExecDlg(TOpenDialog);
ExecDlg(TSaveDialog);
end;
← →
Sergey Masloff (2007-12-19 23:31) [12]Petr V. Abramov © (19.12.07 22:56) [8]
я не о том
TMyObj = class(TSome...
destructor Destroy(); reintroduce; override;
TMyObj.Destroy
begin
освобождаем ресурс1 ==> тут возможно исключение
освобождаем ресурс2
inherited;
end;
MyInst := TMyObj,Create();
FreeAndNil(MyInst);
-- Тут имеем исключение но ресурс не освобожу никогда - к нему нет ссылок
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil; // рубим хвосты
Temp.Free;
end;
← →
Sergey Masloff (2007-12-19 23:33) [13]{RASkov} © (19.12.07 23:25) [11]
У тебя тоже неправильно. Обычно если Execute то нужно что-то сделать с тем что выбрали ;-)
← →
Sergey Masloff (2007-12-19 23:42) [14]Так пойдет?
procedure SelectFont(AFont : TFont);
begin
with TFontDialog.Create(Application) do
try
if Execute then
AFont.Assign(Font);
finally
Free();
end;
end;
// Использование
procedure TForm1.Button1Click(Sender: TObject);
begin
SelectFont(Self.Font);
end;
← →
Loginov Dmitry © (2007-12-19 23:46) [15]> Но как насчет того, что AV возникает при ПЕРВОМ вызове процедуры
> создания диалога (при работе с №1).
Наверно потому, что не все локальные переменные обнуляются автоматически. На TFontDialog.Create() программа не заходит, оттого и AV.
← →
Petr V. Abramov © (2007-12-19 23:48) [16]> Sergey Masloff (19.12.07 23:31) [12]
въехал
:)
← →
Petr V. Abramov © (2007-12-19 23:50) [17]Удалено модератором
← →
Sergey Masloff (2007-12-19 23:56) [18]Удалено модератором
← →
Petr V. Abramov © (2007-12-20 00:08) [19]Удалено модератором
← →
Anatoly Podgoretsky © (2007-12-20 00:10) [20]Удалено модератором
← →
Petr V. Abramov © (2007-12-20 00:14) [21]Удалено модератором
← →
Anatoly Podgoretsky © (2007-12-20 00:17) [22]Удалено модератором
← →
Sergey Masloff (2007-12-20 00:17) [23]Удалено модератором
← →
lookin © (2007-12-20 01:01) [24]> [11] {RASkov} © (19.12.07 23:25)
>>Первый вариант один раз должен отработать нормально, т.е. до первого Free а последующие разы АВ....
Ок, а почему?
>>Вот посмотри вариант:
Спасибо, мне бы со своим разобраться...
> [14] Sergey Masloff (19.12.07 23:42)
Не пойдет, я хотел бы if Execute использовать в вызове TForm1.Button1Click (в твоем примере)
> [15] Loginov Dmitry © (19.12.07 23:46)
Странно, что при создании компонента наново (типа TMyComponent.Create etc) вдруг локальные переменные в локальной процедуре уже существуют...
← →
Германн © (2007-12-20 01:43) [25]
> Странно, что при создании компонента наново (типа TMyComponent.
> Create etc) вдруг локальные переменные в локальной процедуре
> уже существуют...
>
Локальные переменные не могут "уже" существовать. Они существуют сразу как только программа входит в область их видимости!
Тут у тебя "смещение понятий". Локальная переменная (суть указатель на объект) == сам объект. Ты так это понимаешь. И того же понимания хочешь от функции Assigned. Ан нет. Сия функция лишь проверяет равенство конкретного указателя на ноль. И всё!
← →
Германн © (2007-12-20 01:55) [26]И вообще, о птичках.
Похоже разработчики Борланда оказали дурную услугу пользователям Дельфи введя в язык функцию Assigned(). Реально, имхо, она никому не нужна кроме разработчиков компонент. Ну а те, в свою очередь, достаточно грамотные люди. Да и им эта функция не особо и нужна. Наглядности коду она не придаёт, а<> nil
- на три кнопконажатия меньше. (CodeComplite не упоминать. Да и по-моему он в этом случае "молчит в тряпочку")
Ну а прочих пользователей она настолько смутила, что пришлось написать ещё и функцию FreeAndNil. Которая ещё более всё запутала.
← →
J_f_S (2007-12-20 02:24) [27]
> Локальные переменные не могут "уже" существовать
В С - могут :)
← →
Германн © (2007-12-20 02:32) [28]
> Германн © (20.12.07 01:55) [26]
Ещё одна грамматическая ошибка, блин. Хоть и в аглицком, а всё равно блин. :(
P.S.
Старею, да и уже вторую неделю левое колено почти не сгибается. :)
А как участвовать на форуме если коленка не сгибается?
P.P.S
А всё таки я туточки.
:)))
← →
J_f_S (2007-12-20 02:33) [29]
> Старею, да и уже вторую неделю левое колено почти не сгибается.
> :)
Ну не коленом же буквы набиваешь! :)
← →
Германн © (2007-12-20 02:35) [30]
> J_f_S (20.12.07 02:24) [27]
>
>
> > Локальные переменные не могут "уже" существовать
>
> В С - могут :)
>
Эээ. Разъясни. В контексте Германн © (20.12.07 01:43) [25]
← →
Германн © (2007-12-20 02:37) [31]
> J_f_S (20.12.07 02:33) [29]
>
>
> > Старею, да и уже вторую неделю левое колено почти не сгибается.
>
> > :)
>
> Ну не коленом же буквы набиваешь! :)
>
А ты пробовал "набивать буквы лёжа"?
:)
← →
Германн © (2007-12-20 02:39) [32]Не хочу сейчас флудить. Объясни на русском суть твоего сообщения:
> J_f_S (20.12.07 02:24) [27]
>
>
> > Локальные переменные не могут "уже" существовать
>
> В С - могут :)
>
← →
Германн © (2007-12-20 02:49) [33]И ещё раз, как бы ни старались представители СИ сбить нас с толку.
Германн © (20.12.07 01:55) [26]
← →
lookin © (2007-12-20 03:37) [34]> [25] Германн © (20.12.07 01:43)
Я понимаю под локальной переменной ту, которая срабатывает только при входе в некоторую процедуру-функцию. Нет?
← →
lookin © (2007-12-20 03:39) [35]> [25] Германн © (20.12.07 01:43)
а Assigned(***) "Tests for a nil (unassigned) pointer or procedural variable". При чем тут несоотвествие моего кода №1?
← →
lookin © (2007-12-20 03:40) [36]> [33] Германн © (20.12.07 02:49)
не спорю насчет твоей справедливости, только поясни плз
← →
lookin © (2007-12-20 03:41) [37]> [33] Германн © (20.12.07 02:49)
Просто казалось бы, разницы между if not Assigned(Dlg) и Dlg:=nil нету... Нету?
← →
J_f_S (2007-12-20 03:44) [38]Если локальная переменная обьявлена с модификатором 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 - а тут он просто продолжает жить
Элегантно. (Грабли впрочем тут есть, не спорю...)
← →
J_f_S (2007-12-20 03:46) [39]Действительно ли это для Делфей, впрочем, сказать не могу :)
Наверно, нет.
← →
J_f_S (2007-12-20 03:49) [40]А, блин. Очипятки в [38]. Но смысл понятен.
← →
Германн © (2007-12-20 03:54) [41]
> 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]
← →
lookin © (2007-12-20 04:01) [42]Удалено модератором
← →
lookin © (2007-12-20 04:03) [43]Удалено модератором
Примечание: Следи за речью
← →
Германн © (2007-12-20 04:09) [44]
> > [41] Германн © (20.12.07 03:54)
>
> Да как бы ни хрена ты не пояснил... Без обид, мальчик...
>
>
Ну тогда читай книги, старичок. Вот только сумлеваюсь что ты сможешь на смертном одре сказать "Дык я всё-таки хоть что-то понял в Дельфи/Паскале"!
Без обид, Олежка.
← →
lookin © (2007-12-20 04:11) [45]> [44] Германн © (20.12.07 04:09)
Ага, спасибо. Просто нефиг советовать того, что сам не пробовал (таджикская мудрость)...
← →
lookin © (2007-12-20 04:13) [46]Мне б что конструктивное...
← →
Германн © (2007-12-20 04:18) [47]
> lookin © (20.12.07 04:11) [45]
>
> > [44] Германн © (20.12.07 04:09)
>
> Ага, спасибо. Просто нефиг советовать того, что сам не пробовал
> (таджикская мудрость)...
> <Цитата>
>
> lookin © (20.12.07 04:13) [46]
>
> Мне б что конструктивное...
>
Уймись, ради бога!
Ведь когда утром проснутся все прочие форумчане, от тебя не оставят ничего. Придётся менять ник или продолжать позорное существование.
← →
Loginov Dmitry © (2007-12-20 07:35) [48]> Похоже разработчики Борланда оказали дурную услугу пользователям
> Дельфи введя в язык функцию Assigned(). Реально, имхо, она
> никому не нужна кроме разработчиков компонент.
Реально может и не нужна, но все ею пользуются. Удобно при проверке переменных процедурного типа. Записьif Assigned(Proc1) and Assigned(Proc2)
выглядет элегантнее, чемif (@Proc1 <> nil) and (@Proc2 <> nil)
хотя по числу букв - одно и то же )))
← →
Loginov Dmitry © (2007-12-20 07:40) [49]> Foo::GetInstance()::PrintA(); // a = 0 - обьект класса Foo
> создается тут, в GetInstance
> Foo::GetInstance()::PrintA(); // a = 1 - а тут он просто
> продолжает жить
>
>
> Элегантно. (Грабли впрочем тут есть, не спорю...)
В Delphi также можно. Но особого применения {$J+} не получило (этож целых 4 буквы в модуле дополнительно набивать нужно! )))
← →
han_malign © (2007-12-21 16:35) [50]
> Мне б что конструктивное...
>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(в том числе в локалных структурах, массивах и массивах структур), но лучше, даже в этом случае, не привыкать к халяве и инициализировать все явно...
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2008.09.07;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.005 c