Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.24;
Скачать: CL | DM;

Вниз

Exception в конструкторе...   Найти похожие ветки 

 
Jolik ©   (2004-10-11 16:27) [0]

Такая проблема:
есть класс. в конструкторе этого класса создаются всякие ресурсы (кр.секции, память выделяется и пр.). Допустим в начале конструктора произошел 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;



Спасибо!


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


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

Да


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

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


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

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


 
panov ©   (2004-10-11 16:48) [2]

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

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

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;

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


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

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


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


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

нет...

достаточно

MyCrSection.Free();

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


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


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

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


 
Jolik ©   (2004-10-11 18:43) [6]

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


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

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

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


 
Jolik ©   (2004-10-11 19:36) [8]

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


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


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

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


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

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

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


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

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


 
Rouse_ ©   (2004-10-11 22:49) [12]

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


 
KSergey ©   (2004-10-12 07:53) [13]

> [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 (...)


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



Страницы: 1 вся ветка

Текущий архив: 2004.10.24;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.031 c
6-1092483093
MC
2004-08-14 15:31
2004.10.24
разработка протокола


14-1096664608
Folk
2004-10-02 01:03
2004.10.24
Не уж то Билли Гейс такой плохой человек?


3-1095599453
Dio
2004-09-19 17:10
2004.10.24
Установка проекта


14-1097047209
NewDelpher
2004-10-06 11:20
2004.10.24
Где бы скачать хороший учебник по UML с примерами?


1-1096498695
VlaDD
2004-09-30 02:58
2004.10.24
Как организовать нормальный "рандом"??