Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

А я и не знал...   Найти похожие ветки 

 
Вася   (2010-03-06 13:05) [160]


> @!!ex ©   (06.03.10 09:48) [154]
>
> > [153] Вася   (06.03.10 09:25)
>
> У этого самого Init легко делается обработчик исключений.
>
> В то время как для обработки исключения Create как раз и
> придется городить огород


не придется ничего городить.
в 99 процентах случаев такое исключение просто пропускается дальше, и ответственность за него возлагается на вызывающую сторону


> KSergey ©   (06.03.10 10:38)


> "я подложил вам всем свинью, поэтому удобства и приятные
> плюшки дельфи типа Free - не работают".


каким образом перекрытие NewInstance  может привести к неработе именно Free как плюшки? Не очень ясно


 
@!!ex ©   (2010-03-06 13:41) [161]

> [159] DVM ©   (06.03.10 13:05)
> Нет никакой разницы

Ок. Покажите пример. ;)


 
Kerk ©   (2010-03-06 13:56) [162]


> @!!ex ©   (06.03.10 13:41) [161]
>
> Ок. Покажите пример. ;)

Показать пример вышестоящего обработчика?


 
@!!ex ©   (2010-03-06 14:24) [163]

> [162] Kerk ©   (06.03.10 13:56)

ага. пример адекватно обрабатывающий исключение в конструкторе.


 
Kerk ©   (2010-03-06 14:31) [164]


> @!!ex ©   (06.03.10 14:24) [163]
>
> > [162] Kerk ©   (06.03.10 13:56)
>
> ага. пример адекватно обрабатывающий исключение в конструкторе.


function LoadData(...): Boolean;
var
 s: string;
begin
 Result := True;
 // какой-нибудь код
 try
   s := LoadFromFile(FileName);
 except
   Result := False;
   // ну и что еще надо
 end;
 // еще код
end;

function LoadFromFile(aFileName: string): string;
var
 FileStream: TFileStream;
begin
 FileStream := TFileStream.Create(aFileName);
 try
   // Тут всякое чтение и обработка
   // Result := ...
 finally
   FileStream.Free;
 end;
end;


Это если на практике. А вот если представлять сферический код в вакууме, то проблема, да.


 
@!!ex ©   (2010-03-06 14:39) [165]

FileStream := TFileStream.Create(aFileName);
try
  // Тут всякое чтение и обработка
  // Result := ...

  Ты в курсе что этот код выполнится при не валидно FileStream?


 
@!!ex ©   (2010-03-06 14:40) [166]

Я не правильно выразился.
Не выполнится, конечно же.


 
@!!ex ©   (2010-03-06 14:42) [167]

Только в примере отсутствует обработка исключения в конструкторе.
Обработка исключений только для:
  // Тут всякое чтение и обработка
  // Result := ...


 
Kerk ©   (2010-03-06 14:43) [168]


> @!!ex ©   (06.03.10 14:39) [165]
>
> FileStream := TFileStream.Create(aFileName);
> try
>   // Тут всякое чтение и обработка
>   // Result := ...
>   Ты в курсе что этот код не выполнится при не валидно FileStream?

Конечно не выполнится. Именно поэтому LoadData увидит проблему и вернет Falseю


 
Игорь Шевченко ©   (2010-03-06 14:50) [169]

@!!ex ©   (06.03.10 14:42) [167]


> Только в примере отсутствует обработка исключения в конструкторе.


Почему отсутствует ?


>  try
>    s := LoadFromFile(FileName);
>  except


вот она


 
@!!ex ©   (2010-03-06 15:11) [170]

> [169] Игорь Шевченко ©   (06.03.10 14:50)

Это на уровень выше.
С таким же успехом можно вообще не делать обработчик и сказать что исключение обработается стандартным обработчиком.


 
Игорь Шевченко ©   (2010-03-06 15:22) [171]

@!!ex ©   (06.03.10 15:11) [170]


> Это на уровень выше.


Не вижу принципиальной разницы между обработкой ошибок метода LoadFromFile и конкретной обработкой ошибки создания TFileStream.

На мой взгляд, исключение в процедуре сигнализирует о том, что загрузка не сложилась, а почему конкретно она не ложилась - это по типу исключения можно различить.


> С таким же успехом можно вообще не делать обработчик и сказать
> что исключение обработается стандартным обработчиком.


Можно. Только неграмотно.


 
Eraser ©   (2010-03-06 15:23) [172]

> [152] GrayFace ©   (06.03.10 07:46)


> в случае Init пришлось бы городить обработчик исключений?

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

FS := TFileStream.Create();
AnotherObject := TAnotherObject.Create();
Object3 := TObject3.Create();
try
 FS.Init(file, mode);
 ...
 Result := True;
finally
 FS.Free;
 AnotherObject.Free;
 Object3.Free;
end;
end;


 
GrayFace ©   (2010-03-06 15:23) [173]

@!!ex ©   (06.03.10 9:50) [155]
Покажи как грамотно обработать исключение вызванное в Create

Ты про это?
FS:= nil;
try
 FS:= TFilesStream.Create(file, mode);
except
 // обрабатываем
end;


 
Eraser ©   (2010-03-06 15:24) [174]

> FS := TFileStream.Create();
> AnotherObject := TAnotherObject.Create();
> Object3 := TObject3.Create();
> try
> FS.Init(file, mode);
> ...
> Result := True;
> finally
> FS.Free;
> AnotherObject.Free;
> Object3.Free;
> end;
> end;


function SomeFunction: Boolean;
begin
Result := False;
FS := TFileStream.Create();
AnotherObject := TAnotherObject.Create();
Object3 := TObject3.Create();
try
FS.Init(file, mode);
...
Result := True;
finally
FS.Free;
AnotherObject.Free;
Object3.Free;
end;
end;


 
GrayFace ©   (2010-03-06 15:26) [175]

Eraser ©   (06.03.10 15:23) [172]
FS := nil;
AnotherObject := TAnotherObject.Create();
Object3 := TObject3.Create();
try
 FS := TFileStream.Create(file, mode);
 ...
 Result := True;
finally
 FS.Free;
 AnotherObject.Free;
 Object3.Free;
end;
end;

Я бы так же создавал внутри try и Object3.


 
Eraser ©   (2010-03-06 15:31) [176]

> [175] GrayFace ©   (06.03.10 15:26)


> Я бы так же создавал внутри try и Object3.

Но, есть одно НО, тогда уже надо


FS := nil;
AnotherObject := TAnotherObject.Create();
Object3 := TObject3.Create();
try
FS := TFileStream.Create(file, mode);
try
  ...
  Result := True;
finally
  FS.Free;
end;
finally
FS.Free;
AnotherObject.Free;
Object3.Free;
end;
end;

;-)


 
@!!ex ©   (2010-03-06 15:44) [177]

> [173] GrayFace ©   (06.03.10 15:23)

Ага. А теперь мы в функции создает 10 объектов, которые могут сгенерировать исключение в конструкторе. Как будет? Достаточно на 2 написать, суть будет понятна.
Суть в том, что придется каждый Create в свой блок try finally оборачивать, чтобы корректно удалить объекты созданные ранее.
В случае с Init/LoadFromFile/etc будет только один блок try finally и при этом все будет корректно работать.


 
Дмитрий С ©   (2010-03-06 16:04) [178]


> В случае с Init/LoadFromFile/etc будет только один блок
> try finally и при этом все будет корректно работать.

Ну а как же ошибка OutOfMemory ?

И что плохого в обертке каждого Create в try finally ?


 
@!!ex ©   (2010-03-06 16:15) [179]

> [178] Дмитрий С ©   (06.03.10 16:04)

Это возникает, когда все сильно плохо.
Тут уже и свалить приложение не грех в большинстве случаев.


 
Eraser ©   (2010-03-06 16:26) [180]

> [178] Дмитрий С ©   (06.03.10 16:04)


> Ну а как же ошибка OutOfMemory ?

ты оборачиваешь каждое обращение к менеджеру памяти в try..except?

> И что плохого в обертке каждого Create в try finally ?

и, соответственно, каждый Create тоже?


 
Дмитрий С ©   (2010-03-06 16:48) [181]


> Eraser ©   (06.03.10 16:26) [180]

Стремлюсь к этому.
Кроме неявных случаев, где должен сработать сборщик мусора. Например:
SetLength(Str, 123);


 
@!!ex ©   (2010-03-06 16:56) [182]

> [181] Дмитрий С ©   (06.03.10 16:48)

Да ну. Никто так не делает.
Даже VCL пренебрегает такими ошибками.
Слишком мала вероятность их появления и слишком сложно реализовать штатное продолжение работы программы в таких ситуациях. А код поганится сильно.


 
GrayFace ©   (2010-03-06 17:17) [183]

Eraser ©   (06.03.10 15:31) [176]
Но, есть одно НО, тогда уже надо

Не надо. FS.Free происходит в общем try.

@!!ex ©   (06.03.10 15:44) [177]
Суть в том, что придется каждый Create в свой блок try finally оборачивать, чтобы корректно удалить объекты созданные ранее.

Не надо, см. [176].


 
Игорь Шевченко ©   (2010-03-06 17:25) [184]

Про исключения есть хорошая статья, там все собрано в одном месте:
http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1392


 
Дмитрий С ©   (2010-03-06 17:32) [185]


> Да ну. Никто так не делает.
> Даже VCL пренебрегает такими ошибками.
> Слишком мала вероятность их появления и слишком сложно реализовать
> штатное продолжение работы программы в таких ситуациях.
> А код поганится сильно.

Если не делать методы по 9000 строк, то не сильно и поганится.


> Даже VCL пренебрегает такими ошибками.

Очень грустно, если так...


 
@!!ex ©   (2010-03-06 17:55) [186]

> [183] GrayFace ©   (06.03.10 17:17)

FS1:=TFileStream.Create();
FS2:=TFileStream.Create(); <-- Тут исключение, FS1 не удален.


 
GrayFace ©   (2010-03-06 18:29) [187]

@!!ex ©   (06.03.10 17:55) [186]
FS2:= nil;
FS3:= nil;
FS4:= nil;
FS5:= nil;
FS1:= TFileStream.Create();
try
 FS2:= TFileStream.Create();
 FS3:= TFileStream.Create();
 FS4:= TFileStream.Create();
 FS5:= TFileStream.Create();
finally
 FS1.Free;
 FS2.Free;
 FS3.Free;
 FS4.Free;
 FS5.Free;
end;


 
oxffff ©   (2010-03-06 19:00) [188]


> GrayFace ©   (05.03.10 17:05) [84]
> oxffff ©   (05.03.10 14:57) [48]
> Берем перекрываем аллокатор newinstance без очистки на 0
> для неуправляемых объектов. Получаем исключение на free.
>  Гарантий нет!!!
> Это проблема того, кто перекрыл. Если кто-то хочет вызвать
> ошибку, то он найдет миллион способов это сделать.


Если следовать вашей логике, то и инициализация локальных переменных должна проходить по такой же схеме. Однако так не происходит.
Не объясните почему?


 
GrayFace ©   (2010-03-06 19:05) [189]

oxffff ©   (06.03.10 19:00) [188]
Не понял, что с инициализацией локальных переменных?


 
@!!ex ©   (2010-03-06 19:05) [190]

> [187] GrayFace ©   (06.03.10 18:29)

Красиво. :)
Только, что-то никто так не делает.
Мне вариант с LoadFromFile нравится больше.


 
Игорь Шевченко ©   (2010-03-06 19:05) [191]

GrayFace ©   (06.03.10 18:29) [187]


> FS2:= nil;
> FS3:= nil;
> FS4:= nil;
> FS5:= nil;


Вот это зачем ?


 
GrayFace ©   (2010-03-06 19:12) [192]

А, не инициализируются 0, если не string и т.п.?
1) Так сделано.
2) С локальными переменными чаще связана критическая по скорости функциональность и на ней это может сильнее сказаться, чем инициализация класса на скорости его создания.
3) Логика конструкторов/деструкторов сложнее, чем логика простой процедуры, для них это важнее.


 
GrayFace ©   (2010-03-06 19:17) [193]

Прошлый пост - ответ на [188].

Игорь Шевченко ©   (06.03.10 19:05) [191]
Вот это зачем ?

Иначе, если исключение вызовет FS2.Create, то FS2-5 останутся не инициализированными и Free вызовет AV.


 
Игорь Шевченко ©   (2010-03-06 19:23) [194]

GrayFace ©   (06.03.10 19:17) [193]


> Иначе, если исключение вызовет FS2.Create, то FS2-5 останутся
> не инициализированными и Free вызовет AV.


Чудны дела твои, господи.


 
oxffff ©   (2010-03-06 19:28) [195]


> GrayFace ©   (06.03.10 19:12) [192]
> А, не инициализируются 0, если не string и т.п.?
> 1) Так сделано.
> 2) С локальными переменными чаще связана критическая по
> скорости функциональность и на ней это может сильнее сказаться,
>  чем инициализация класса на скорости его создания.
> 3) Логика конструкторов/деструкторов сложнее, чем логика
> простой процедуры, для них это важнее.


1. Да.
2. Спорно. Бывает наоборот.
3. Уточните. Как связан Free c логикой конструкторов и деструкторов.


 
oxffff ©   (2010-03-06 19:40) [196]


> 2. Спорно. Бывает наоборот.


В смысле порой инициализация локальных переменных бывает медленней чем обнуление непрерывного участка.


 
GrayFace ©   (2010-03-06 20:33) [197]

oxffff ©   (06.03.10 19:28) [195]
3. Уточните. Как связан Free c логикой конструкторов и деструкторов.

Пожалуй, я поторопился. Это навеяно дискуссией с Alkid"ом.
Субьективно, инициализация нулями класса чаще полезна. И для ссылок на создаваемые в конструкторе объекты, и для event"ов, и для инициализируемых нулями полей. По сути, инициализация нулями оказывается лишней только для простых свойств, которым присваивается отличное от нуля значение в конструкторе - таких обычно не много.

Ну и еще пункт:
4) Не инициализированная локальная переменная приводит к warning"у, благодаря которому переодически отлавливается ошибка. При иициализации нулями ушла бы и эта проверка. В случае с классами такой проверки нет и иициализации нулями, наоборот, уменьшает вероятность ошибок, связанных с не инициализированными полями.


 
GrayFace ©   (2010-03-06 20:37) [198]

Причем, если та ситуация с Free, с которой мы начали, произойдет в процедуре, то выскочит этот warning.


 
Игорь Шевченко ©   (2010-03-06 20:41) [199]

GrayFace ©   (06.03.10 20:33) [197]


> В случае с классами такой проверки нет


И быть не может


 
Kerk ©   (2010-03-06 21:26) [200]

Необходимость делать вложенные try-finally скорее всего говорит только о том, что код нужно переписать (например, как в [164]). Это и на читаемости кода здорово скажется и утечек памяти мы не допустим, поленившись лишний раз try-finally написать.



Страницы: 1 2 3 4 5 6 вся ветка

Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.82 MB
Время: 0.113 c
15-1272634082
JohnKorsh
2010-04-30 17:28
2010.08.27
Как в Windows7 отключить UAC?


6-1216982606
Uzer32.dll
2008-07-25 14:43
2010.08.27
Доступ к запароленым шарам


15-1266060403
GanibalLector
2010-02-13 14:26
2010.08.27
Транссиб


3-1238562946
TheEd
2009-04-01 09:15
2010.08.27
как вычитать isert ы, произошедшие в триггере одной из таблиц


2-1271096606
Б
2010-04-12 22:23
2010.08.27
Как узнать, что в приложении течёт память?





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