Форум: "Основная";
Текущий архив: 2003.03.13;
Скачать: [xml.tar.bz2];
ВнизFree в конструкторе Найти похожие ветки
← →
jack128 (2003-03-01 21:04) [0]День добрый. Есть наследник TFileStream, который описывает файл определенного формата.
Если в заголовоке файла находится строка SVktArhiveTitle, то это файл моего формата и с ним можно работать дальше, иначе поднимаем исключение(чтоб объект не создался).
Но в этом случаи файл не закроется!!!(ведь деструктор не вызывался).
Насколько коректно вызывать Free в конструкторе??
Примерный код :
constructor TWin32VktArhive.Create(const FileName: string; Mode: Word; IsDayArhive : boolean);
var Title : string;
begin
inherited Create(Filename, Mode);
if Mode = fmCreate then begin
Write(SVktArhiveTitle[1],Length(SVktArhiveTitle));
Write(IsDayArhive,SizeOf(IsDayArhive));
FIsDAyArhive := IsDayArhive;
end else begin
if Size < Length(SVktArhiveTitle) + SizeOf(IsDayArhive) then
raise Exception.CreateFmt("
← →
uw (2003-03-01 22:02) [1]Так закрой и возбуждай и дело с концом.
← →
mike-d (2003-03-01 22:21) [2]В Turbo Pascal для этой цели существовала процедура Fail (она и Delphi есть, только нигде не нашел описания). Вызов деструктора в конструкторе работает, но наверное не совсем это хорошо с точки зрения программирования :).
Попробуй перекрыть метод AfterConstruction - там вызовешь деструктор и исключение.
← →
Набережных С. (2003-03-01 22:27) [3]>Насколько коректно вызывать Free в конструкторе??
Ни насколько. Чего проще - сгенерить исключение в конструкторе, поставив точку останова в деструкторе. Пол-минуты и никаких вопросов.
← →
jack128 (2003-03-01 22:34) [4]2 mike-d © (01.03.03 22:21)
я тут вспомнил - была дисскусия более общего плана:
насколько коректно вызывать деструктор из любого метода объекта(с точки зрения программирования :))(имеется в виду последним оператором метода) - тогда к общему мнению помнится не пришли...
Ну хорошо. Всем спасибо - вопрос закрыт
← →
Юрий Зотов (2003-03-01 22:35) [5]> иначе поднимаем исключение(чтоб объект не создался).
Не совсем так. Дело в том, что если при входе в Ваш конструктор объект УЖЕ создан, даже еще ДО вызова inherited Create. А далее любое непогашенное исключение в Вашем конструкторе приводит к автоматическому уничтожению только что созданного объекта. Для этого компилятор генерит специальный скрытый код. Схема получается примерно такая:
NewInstance;
try
InitInstance; // Обнуляет выделенную под объект память.
... // Здесь отрабатывает код Вашего конструктора и вся цепочка
... // унаследованных конструкторов, если был вызван inherited
except
FreeInstance;
raise
end;
Есть нюансы, зависящие от того, как именно был вызван конструктор, но это в данном случае неважно. Важно то, что когда Вы в конструкторе возбуждаете исключение, объект не то чтобы "не создается" (он все равно создается - вернее, он уже БЫЛ создан), а уничтожается (причем автоматически).
То есть, никаких Free Вам специально вызывать не нужно, а нужно перед возбуждением исключения просто вызвать FileClose(Handle).
← →
Набережных С. (2003-03-01 23:23) [6]Если в конструкторе генерится исключение, то обязательно вызывается деструктор объекта, там и следует, ИМХО, штатно освобождать ресурсы.
← →
jack128 (2003-03-02 01:48) [7]2 Юрий Зотов © (01.03.03 22:35)
Я до конца не понял..
FreeInstance освобождает память из под объекта. Так?
Но что бы освободить ресурсы захваченные inherited Create(...) (хендлы и прочее) в ОБЩЕМ случаи следует вызвать Free(который в моём примере, действительно, сводится к CloseHandle(..))?
Я ведь мог и не иметь доступа к Handle (например если бы это было Private свойство)
Набережных С. (01.03.03 23:23)
Не совсем ясно >обязательно вызывается деструктор объекта< Кем? если мой, то я так и предпологал, если Delphi - то это не так...
← →
Набережных С. (2003-03-02 08:11) [8]>jack128 © (02.03.03 01:48)
>если Delphi - то это не так...
Что не так? Если исключение возбуждено в конструкторе, то в процессе его обработки обязательно будет вызван деструктор. И этот код вставляется средой автоматически. В частности, для этого служит член ConstructedObject структуры TExcFrame. Я ж сказал - поставь точку останова.
← →
theodor_iv (2003-03-02 10:46) [9]2 jack128:
По этому поводу хэлп говорит следующее:
If an exception is raised during execution of a constructor that was invoked on a class reference, the Destroy destructor is automatically called to destroy the unfinished object.
Что в переводе на русский означает никакого Free в конструкторе, только raise и все будет ОК.
Например:
type
TTest = class
constructor Create;
destructor Destroy; override;
end;
constructor TTest.Create;
begin
raise Exception.Create("Hello, World!");
end;
destructor TTest.Destroy;
begin
ShowMessage("GoodBye, World!");
inherited;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
T: TTest;
begin
T := TTest.Create;
end;
Эта программа сначала выводит GoodBye, что показывает, что деструктор действительно вызывается автоматически, если в конструкторе произошло исключение.
← →
jack128 (2003-03-02 13:46) [10]2 Набережных С. (02.03.03 08:11)
2 theodor_iv (02.03.03 10:46)
Каюсь, был не прав. Признаю себя ослом и жду дальнейших распорежений (с) "Остров сокровищ"
← →
Danilcha (2003-03-03 11:29) [11]А можно Abort() использовать.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.03.13;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.009 c