Форум: "Основная";
Текущий архив: 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.037 c