Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
7-39610
Amien
2003-01-19 15:43
2003.03.13
Как узнать/изменить серийный номер тома HDD?


14-39526
pcgamer
2003-02-26 11:45
2003.03.13
Кодеры () и дизайнеры. Давайте объединяться и обмениваться инфой.


6-39444
manner
2003-01-24 19:51
2003.03.13
Как запустить из Delphi IE с определенным URL?


3-39189
Shrek
2003-02-19 12:54
2003.03.13
Как изменить тип поля в MySQL?


1-39249
Tihas
2003-02-26 23:45
2003.03.13
Вопрос оперторов...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский