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

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

Exception в конструкторе...


Jolik ©   (2004-10-11 16:27:00) 

Такая проблема:
есть класс. в конструкторе этого класса создаются всякие ресурсы (кр.секции, память выделяется и пр.). Допустим в начале конструктора произошел exception  - соответственно не создались никакие ресурсы. Если в конструкторе произошел exception delphi выходит из конструктора и вызывается деструктор (хотя, кстати, никто его об этом не просит!). В деструкторе, естественно, ресурсы освобождаются - но ведь они и не создавались? Происходит GPF - как выкручиваться из этой ситуации? Перед удалением в деструкторе проверять на 0 (nil)? Что то мне такой метод не очень ндравиться:((( Ну а, например, кр.секция это структура - с ней как быть?
Поясню:


TMyClass = class
 MyCrSection :TRTLCriticalSection;
 MyMemory : pointer;
 MyEvent : THandle;

 constructor Create;
 destructor Destroy; override;
end;

constructor TMyClass.Create;
begin
 GetMem(MyMemory, 1024);
 ...
 Опс! Здесь произошло исключение!
 Отсюда прыгаем в деструктор!
 ...
 MyCrSection:=CreateEvent(nil,TRUE,TRUE,nil);
 InitializeCriticalSection(MyCrSection);
end;

destructor TMyClass.Destroy; override;
begin
 if MyMemory <> nil then FreeMem(MyMemory);

 if MyCrSection<>0 then CloseHandle(MyCrSection);

// а здесь как проверить? Это же структура... По полям шнырять?
 DeleteCriticalSection(MyCrSection);
end;



Спасибо!


KSergey   (2004-10-12 07:53:00) [1]

> [12] Rouse_ ©   (11.10.04 22:49)
> try...except в конструкторе

Это еще зачем???

> [8] Jolik ©   (11.10.04 19:36)
> Т.е. в конструкторе
> следует указать строчку MyFile := INVALID_HANDLE_VALUE;
> На что Delphi выдает варнинг, тапа, мол, значение присвоил
> - но нигде не используешь...

Наверное пишете что-то вроде

MyFile := INVALID_HANDLE_VALUE;
MyFile := OpenFile (...)


Тогда конечно.. хотя... А, к стати: вы пользуетесь апишной ф-цией или дельфовой? АПИшные по идее исключения не генерят...

А вот если написать

MyFile := INVALID_HANDLE_VALUE;
...жутко исключительный код...
MyFile := OpenFile (...)


то, вероятно, никто не не заругается...


Rouse_   (2004-10-11 22:49:00) [2]

Ребят вы о чем? Какие флаги инициализации?
1. Инициализируем в значение по умолчанию...
2. Есть такая замечательная вещь как try...except в конструкторе
3. В конструкторе не лишне было бы проверить условия при которых может возникнуть исключение...
4. В основном ошибки такого плана возникаю при HandleAllocated = False, т.о. можно перенести в Loaded


Cobalt   (2004-10-11 22:34:00) [3]

2 Jolik ©   (11.10.04 19:36) [8]
Может, действительно нигде не используешь пока? Особливо, если это private-поле


jack128   (2004-10-11 19:42:00) [4]

Jolik ©   (11.10.04 19:36) [8]
мол, значение присвоил - но нигде не используешь...

как это не используешь?? А в деструкторе??


Суслик   (2004-10-11 19:40:00) [5]


>  [8] Jolik ©   (11.10.04 19:36)

посмотри на первый ответ Panov про флаги инициализации.
Если мне нужно отрабатывать иницилизирован/не инициализирован для НЕ объектов, то я делаю именно так как сказал Panov.


Jolik   (2004-10-11 19:36:00) [6]

Т.е. если я правильно понял, все ресурсы следует проинициализировать недействительными значениями, которые проверять затем в деструкторе.
тогда другая проблема - не всегда значение поля класса по умолчанию ("0") совпадает с недействительным значением ресурсов.
Например создаем ресурс - файл.
При создании класса (до вызова конструктора) все поля устанавливаются в 0. инвалидный же хэндл файла (Тот что возвращает FileOpen)- INVALID_HANDLE_VALUE. Это значение -1. Т.е. в конструкторе следует указать строчку MyFile := INVALID_HANDLE_VALUE; На что Delphi выдает варнинг, тапа, мол, значение присвоил - но нигде не используешь...
Может это конечно занудство, но так хочется написать прогу без хинтов и варнингов :)))


panov   (2004-10-11 18:48:00) [7]

>Суслик ©   (11.10.04 18:09) [4]
>Erik1 ©   (11.10.04 18:08) [3]

Ресурсы - это не обязательно объекты - экземпляры классов.
Могут быть динамические строки, структуры, объекты ядра, память и пр.


Jolik   (2004-10-11 18:43:00) [8]

MyCrSection это рекорд...


Суслик   (2004-10-11 18:10:00) [9]


> любых случаях.

под "любыми случаями" я имел в виду случай использования в деструкторе. Ясно, что иногда freeandnil лучше. Но в конструкторе он за редким исключением не нужен.


Суслик   (2004-10-11 18:09:00) [10]


> А разве не проще и красивей написать?
> if Assigned(MyCrSection) then
>  FreeAndNil(MyCrSection);

нет...

достаточно

MyCrSection.Free();

любых случаях.


Erik1   (2004-10-11 18:08:00) [11]

А разве не проще и красивей написать?
if Assigned(MyCrSection) then
 FreeAndNil(MyCrSection);


panov   (2004-10-11 16:48:00) [12]

А больше никак.

В случае, если много различных выделяемых ресурсов, можно вести своеобразный протокол:

constructor Create
begin
 CountResource := 0;

 CreateResource1...
 inc(CountResource);

 CreateResource2...
 inc(CountResource);

 CreateResource3...
 inc(CountResource);

 ...
end;

destructor Destroy;
begin
 if CountResource>0 then
 begin
   DeleteResource1...
 end;
 Dec(CountResource);
 if CountResource>0
 begin
   DeleteResource2...
 end;

и.т.д.
Примерно так...


Суслик   (2004-10-11 16:29:00) [13]


>  Перед удалением в деструкторе проверять на 0 (nil)?

Да


> Что то мне такой метод не очень ндравиться:(((

пиши на бейсике


> Ну а, например, кр.секция это структура - с ней как быть?

флажок использовать, например. Или в каждом конкр. случае читать доку, что будет если удалить структуру не созвав ее.


Наверх

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