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

Вниз

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

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

Наверх




Память: 0.83 MB
Время: 0.077 c
2-1273728307
Irisss
2010-05-13 09:25
2010.08.27
вкладка Data Explorer


2-1274209434
Сид
2010-05-18 23:03
2010.08.27
Проверить значение TDBLookupComboBox


2-1272341393
Игорь
2010-04-27 08:09
2010.08.27
GetProcessAffinityMask


15-1265491802
Юрий
2010-02-07 00:30
2010.08.27
С днем рождения ! 7 февраля 2010 воскресенье


2-1266325693
Rail
2010-02-16 16:08
2010.08.27
как правильно указать путь к бд