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

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.022 c
4-39637
ddenisv
2003-01-21 18:47
2003.03.13
Service + DLL+Help me


14-39516
artul
2003-02-25 10:40
2003.03.13
DBEXpress где взять


6-39441
KasAlex
2003-01-22 15:53
2003.03.13
Сокеты. Нет коннекта при определенном условии


14-39554
Dunkan
2003-02-26 11:19
2003.03.13
нажатие нескольких клавиш...


1-39372
ЮРИЙ_К
2003-02-28 17:17
2003.03.13
Как обратиться к Item и SubItem компонента ListView