Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.10.24;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.039 c
14-1096891606
Guest
2004-10-04 16:06
2004.10.24
Перестал пахать комп, пень первый 166 MHz


14-1096877994
Слоник
2004-10-04 12:19
2004.10.24
Сетевая обучающая игровая программа free-ware


3-1096279576
barkot
2004-09-27 14:06
2004.10.24
fkCalculated ???


3-1096027384
ceval
2004-09-24 16:03
2004.10.24
Подскажите как сделать это при помощи ADOQuery ?


14-1097072739
infom
2004-10-06 18:25
2004.10.24
Где взять функция, которая парсит запрос ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский