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

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

Освобождение ресурса в finally


Страницы:   1 2 ... 24 25 26 27 28 29 30 31 32 33

Arinyshka ©   (2008-04-23 12:17:00) 

Не подскажете еще один момент:
Есть процедура, выглядит примерно так

procedure TSetPayFrm.BtnAddImageClick(Sender: TObject);
var  TempBitmap:TBitmap;
begin
if not(opendialog1.Execute) then  exit;
try
 TempBitmap  := TBitmap.Create;
 TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;
end;

На освобождение  TempBitmap.Free; выдает варнинг
[Warning] uSetPaymentMain.pas(313): Variable 'TempBitmap' might not have been initialized
Не смертельно, но непонятно... почему варнинг? При изменениии условия и включении всей конструкции в один блок begin..end ситуация не менялась.


Palladin   (2008-04-24 14:26:00) [561]


> Объектов 5-6 наберется.

каких например?


ANB   (2008-04-24 14:24:00) [562]

Простенький пример :
имеем хитрый текстовый файл, который надо разобрать на клиенте, закачать в БД и потом обработать уже хранимкой.
В процессе разбора иногда придется опять таки обращаться к БД за уточнением информации.
Ошибочные строки надо записать в другой файл и при этом еще вести лог обработки.
Объектов 5-6 наберется.

Естественным подходом в таком случае будет создать все объекты заранее и только по окончании процедуры удалить.

Городить вложенные 5-6 трай - файнелли - жуткий изврат. Весь код фактически вправо уйдет.

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

Это что получится - на кажную строчку в файнелли надо отдельный блок заводить ? А если потом выяснилось, что объект не нужен был - обратно все убирать ?

ИМХО - в функции должен быть один блок трай - файнелли.


Palladin   (2008-04-24 14:21:00) [563]


> ANB   (24.04.08 14:13) [89]

кто не писал? я неписал?


ANB   (2008-04-24 14:13:00) [564]


> Palladin ©   (24.04.08 13:57) [86]
> Обниление идентификаторов и перенос конструктора в try выглядит
> как-то неестественно, но это так, придирка не посуществу.
>  Другое беспокоит, не знаю как кто, но у меня обычно в локальных
> перменных не числится больше трех-четырех объектов, а если
> и числится, то используются они в разных временных рамках
> и на каждый идет блок try finally, если же происходит раздувание
> количества, то это первая ласточка к разделению процедуры/метода
> на несколько шагов и оформлении их в виде отдельных процедур/методов.
>  Разделяй и влавствуй, как говорится. Так что, обниление
> идентификаторов, это совет тем кто не умеет структурировать
> программу и лепит все в один.

Значится не писал достаточно сложных программ. :)


Восхищенный   (2008-04-24 14:11:00) [565]

> Palladin ©   (24.04.08 13:57) [86]

В самую точку.


ANB   (2008-04-24 14:10:00) [566]


> ЮЮ ©   (24.04.08 12:36) [76]
> > [74] ANB   (24.04.08 12:30)
>
> > Вобчем то да. Но могут быть разные глюки потом
>
>
> Глюки после смерти? Если они есть, значит проблемы в другом
> месте кода и это счастье, что тебе удалось уловить их хотя
> бы опосредованно.

Да я не нарывался ни разу.


Palladin   (2008-04-24 13:57:00) [567]

Обниление идентификаторов и перенос конструктора в try выглядит как-то неестественно, но это так, придирка не посуществу. Другое беспокоит, не знаю как кто, но у меня обычно в локальных перменных не числится больше трех-четырех объектов, а если и числится, то используются они в разных временных рамках и на каждый идет блок try finally, если же происходит раздувание количества, то это первая ласточка к разделению процедуры/метода на несколько шагов и оформлении их в виде отдельных процедур/методов. Разделяй и влавствуй, как говорится. Так что, обниление идентификаторов, это совет тем кто не умеет структурировать программу и лепит все в один.


Jack128_   (2008-04-24 13:43:00) [568]


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

не фига. как раз если не обниливать переменную после уничтожения - то проблема может и не проявиться(точнее проявиться - но у юзера), а вот если юзать FreeAndNil - то ошибка ГАРАНТИРОВАННО проявиться.

var
 O: TObject;
begin
 O := TObject.Create;
 try
   Caption := O.ClassType.ClassName;
 finally
   O.Free;
 end;
 Caption := O.ClassType.ClassName; // ошибочный код. Но AV не будет.
end;


Поэтому я почти всегда юзаю FreeAndNil


Восхищенный   (2008-04-24 13:20:00) [569]

> {RASkov} ©   (24.04.08 13:01) [83]

Поставь на первой строке конструктора бряк и посмотри, что будет в окне CPU передэтим бряком. Там увидишь вызов функции из System (не помню точное название, что-то типа _CreateInstance), которая реально выделяет память и создает объект (ее код можно посмтреть). А на первой строке конструктора объект уже создан и даже проинициализирован (InitInstance), и сам конструктор, по сути, всего лишь дает возможность его дополнительной (юзерской) инициализации. Ну и есть там еще блок try-except (тоже вставленный компилятором) - это уже к сабжу относится (разрушение объекта при исключении в конструкторе).


{RASkov}   (2008-04-24 13:01:00) [570]

> [82] Восхищенный   (24.04.08 12:57)
> Ты, возможно, удивишься

Нет, не удевлюсь, так как то что мы видим в редакторе кода для компилятора это совсем другое :)
А честно - "не знал"... Т.е. именно такое про конструктор слышу в первый раз.


Восхищенный   (2008-04-24 12:57:00) [571]

> {RASkov} ©   (24.04.08 12:50) [80]

> Его нужно применять к классу, иначе(если к объекту: Obj.Create;) это не
> конструктор а вызов метода Create без распределения памяти....

Ты, возможно, удивишься, но метод Create не выделяет память даже если он был вызван и через ссылку на класс. Память выделяется другим кодом, который в этом случае автоматически вставляется компилятором перед непосредственным вызовом Create. Это просто compiler-magic фича такая и к классовым методам она никакого отношения не имеет.


{RASkov}   (2008-04-24 12:50:00) [572]

> [79] Kolan ©   (24.04.08 12:46)
> так что, имхо, классовый.

Коструктор, да. Его нужно применять к классу, иначе(если к объекту: Obj.Create;) это не конструктор а вызов метода Create без распределения памяти....

Но я зря его(конструктор) подчеркнул, так как разговор был о Free)


Восхищенный   (2008-04-24 12:50:00) [573]

> Kolan ©   (24.04.08 12:46) [79]

Проверь, что такое Self внутри конструктора - и имхо твое изменится, и имхом быть перестанет.


Kolan   (2008-04-24 12:46:00) [574]

> но не классовый он…

Имхо, слово constructorподразумевает class function, так что, имхо, классовый.


{RASkov}   (2008-04-24 12:42:00) [575]

> [70] ZENsan ©   (24.04.08 12:23)

 TObject = class
    constructor Create;
    procedure Free;
    classfunction InitInstance(Instance: Pointer): TObject;
   procedure CleanupInstance;
   function ClassType: TClass;
    classfunction ClassName: ShortString;
    classfunction ClassNameIs(const Name: string): Boolean;
......


Я конечно загнул с приватным :) но не классовый он....


Восхищенный   (2008-04-24 12:40:00) [576]

> ZENsan ©   (24.04.08 12:26) [72]

> Constructor i Destructor - единственные класс методы до реализации класс
> методов в делфи начиная по моему с 2005-ого..

1. Конструктор и деструктор - вообще не классовые методы.

2. Классовые методы реализованы во всех версиях Delphi, начиная аж с 1.

3. В [65] Плохиш дал очень хороший совет. Конечно, можно и дальше переливать здесь из пустого в порожнее, но лучше все же последовать этому совету.


ЮЮ   (2008-04-24 12:36:00) [577]

> [74] ANB   (24.04.08 12:30)

> Вобчем то да. Но могут быть разные глюки потом


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


ЮЮ   (2008-04-24 12:32:00) [578]

> Я именно про случай если это локальные переменные не константы…


зачем тогда
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
end;


так разве менее красиво
finally
Obj1.Free;
Obj2.Free;
end;

P.S. учитывая, что Obj2 := TObj2.Create; часто вызывает исключение, очень вероятно, что при удачном создании обоих объектов упадет с исключением Obj1.Free; и Obj2 останется неосвобожденным :)


ANB   (2008-04-24 12:30:00) [579]


>  то нет смфсла в их обNilениее в finally

Вобчем то да. Но могут быть разные глюки потом. Ну его нафиг - мне что жалко один раз выполнить короткое присваивание ? Тем более оно в функции живет.


ZENsan   (2008-04-24 12:27:00) [580]

Если поля обйекта то конечно. Я именно про случай если это локальные переменные не константы..


Страницы:   1 2 ... 24 25 26 27 28 29 30 31 32 33

Наверх

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