Модераторы: Snowy, MetalFan, bems, Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание объекта, AV 
V
    Опции темы
Rohoss
Дата 20.6.2008, 01:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: нет
Всего: 18



Код

MyClass := TComponent.Create(Self);
try

finally
  MyClass.Free;
end;

Это стандартный шаблон кода, входящий в состав среды Delphi 2006, который можно выбрать нажатием плавишь Ctrl + J. Почему объект создаётся перед блоком try, а не внутри него? smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Beltar
Дата 20.6.2008, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 0
Всего: 7



Помнится на DelphiKingdom в разделе "Свитки" были статейки на тему безопасности языков программирования, где как раз и обсуждались обломы в конструкторе и многое другое.

Статьи назывались: "ЯП, ОПП и т.д. и т.п. в свете безопасности программирования" http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=301 всего 4 части и ответ на нее "Игра отражений" http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=346.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
pseud
Дата 20.6.2008, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

Репутация: 10
Всего: 40



Цитата(Rohoss @  20.6.2008,  01:15 Найти цитируемый пост)
 Почему объект создаётся перед блоком try, а не внутри него?  


потому что 
Код

TComponent.Create

может отработать с ошибками и в MyClass у тебя останется nil. И в итоге ты обратишься в MyClass.Free к методу несуществующего объекта и получишь AV



--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Beltar
Дата 20.6.2008, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 0
Всего: 7



Цитата

И в итоге ты обратишься в MyClass.Free к методу несуществующего объекта и получишь AV


Причем здесь это? Все равно Free будет вызвано, и если Create не отработал, то ты получишь AV. А конструктор в try запихивать не надо, потому что он по умолчанию в защищенном блоке работает. Так что шаблон вполне логичный.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
pseud
Дата 20.6.2008, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

Репутация: 10
Всего: 40



Цитата(Beltar @  20.6.2008,  10:36 Найти цитируемый пост)
Причем здесь это? Все равно Free будет вызвано, и если Create не отработал, то ты получишь AV.

именно так я и написал....

Цитата(Beltar @  20.6.2008,  10:36 Найти цитируемый пост)
 А конструктор в try запихивать не надо, потому что он по умолчанию в защищенном блоке работает

интересно в каком защищенном блоке работает constructor в примере?
Код

constructor TMyClass.Create(AOwner: TComponent);
begin
  raise Exception.Create('ой');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  c: TMyClass;
begin
  c := TMyClass.Create(Self);
  try
  finally
    c.Free;
  end;
end;



--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Beltar
Дата 20.6.2008, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 0
Всего: 7



Ссылки выше. "Игра отражений" Не забываем, что Create это не только и не столько конструктор, написанный разработчиком класса.
Присваивание же переменной nil это самое логичное поведение при сбое, которое легко проверить без try.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Rohoss
Дата 22.6.2008, 04:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: нет
Всего: 18



Так, что ли?
Код

MyClass := TComponent.Create(Self);
if MyClass=nil then Exit;
try

finally
  MyClass.Free;
end;

А зачем тогда try finally? Если у кого то есть рабочий пример использования, пожалуйста приведите с пояснениями. smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
MetalFan
Дата 22.6.2008, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



Цитата(Rohoss @  22.6.2008,  04:57 Найти цитируемый пост)
Так, что ли?

не так.

смысл в том, что код в секции finally выполняется при любом раскладе в секции try.
чаще всего она используется для своевременного освобождения захваченных ресурсов.

Rohoss, проверка во 2й строке не имеет смысла, ибо в случае исключения в конструкторе мы на нее не попадем, соотв. если исключение не возникнет, то и условие не выполнится.

Пример:
Код

var
  lPtr: pointer;
  lObj: TObject;
begin
  GetMem( lPtr, SomeSize );
  try //при любом раскладе гарантируем освобождение ресурсов
    ...
    if Condition then exit; //выход, но не из функции, а в секцию finally
    ...
    lObj.Property := Value; //ловим AV, но сначала в finally!
  finally 
    FreeMem( lPtr );
  end;



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Rohoss
Дата 22.6.2008, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: нет
Всего: 18



Так почему мы попадём в секцию finaly, если исключение возникнет при выделении памяти, до блока try?

Код

var
  lPtr: pointer;
  lObj: TObject;
begin
  GetMem( lPtr, SomeSize ); //Возникает АV, но почему оно обрабатывается?  Оно же возникло перед try
  try 
    ...
    if Condition then exit; 
    ...
    lObj.Property := Value; 
  finally 
    FreeMem( lPtr );
  end;


Это сообщение отредактировал(а) Rohoss - 22.6.2008, 10:35


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Rrader
  Дата 22.6.2008, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 18
Всего: 191



А мы туда не попадем. Если исключение (reOutOfMemory) сгенерится в GetMem, память просто не будет выделена, а NIL и освобождать не нужно. Но мы и не дойдем до try-finally-end. Тут речь о том, что блок try-finally-end позволяет гарантированно освобождать валидные ресурсы.

Вот, final-версия этого поста smile 

Это сообщение отредактировал(а) Rrader - 22.6.2008, 11:02


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Rohoss
Дата 22.6.2008, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: нет
Всего: 18



Так этот блок не обрабатывает исключений в конструкторе объекта?
Я имею ввиду то, что в конструкторе, помимо выделения памяти может много ещё чего содержатся. 

А если всё же память будет равна nil, мы перейдём в блок try, с него естественно в finaly, а там MyClass.Free , обращение к методу несуществующего класса…
Сори за такие вопросы, просто хочу понять, как это работает…


Это сообщение отредактировал(а) Rohoss - 22.6.2008, 10:52


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Rrader
  Дата 22.6.2008, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 18
Всего: 191



1. Обо всех опасных действиях в конструкторе нужно заботиться самостоятельно и защищать их теми же try-finally-end.

2. Возникает исключение в конструкторе. Если все находится в правильно оформленном защищенном SEH-блоке(try-finally-end), то ресурсы гарантированно освободятся. Что происходит потом? А ничего, выход.

Смотри:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  F: TFileStream;
begin
  F := TFileStream.Create('NIL', fmOpenReadWrite);
  try
    F.Seek(0, soFromEnd);
  finally
    F.Free;
  end;
end;

Так вот здесь мы не дойдем до Seek никогда. Понятно теперь? smile 


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Rohoss
Дата 22.6.2008, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: нет
Всего: 18



Rrader , тебе не надоело редактировать своё сообщение, пиши нове, а то хз что получается.  smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Rrader
  Дата 22.6.2008, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 18
Всего: 191



Rohoss, это чтоб понятнее было исправлял =)
Вот тебе еще пример:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  P: Pointer;
begin
  GetMem(P, 100000000000);
  try
     P := 0;
  finally
     FreeMem(P);
  end;
end;

До FreeMem дело не дойдет, даже до try не дойдет, если будет ошибка Out Of Memory.

Это сообщение отредактировал(а) Rrader - 22.6.2008, 10:59


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Rohoss
Дата 22.6.2008, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: нет
Всего: 18



Угу, ну тогда всё логично. Просто я почему то думал что этот блок защищает и от ошибок конструктора…


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1079 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.