Форум: "Потрепаться";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];
ВнизНавеяло недавними обсуждениями Найти похожие ветки
← →
Ega23 © (2004-08-17 19:57) [0]Как правильно организовать создание, работу и освобождение объекта, а также передать "наверх" исключение, если такое возникнет.
С одним экземпляром понятно:
try
Obj:TFirstObj.Create
try
......
работа с объектом
......
finally
Obj.Free;
end;
except
raise
end;
А вот как быть с двумя?
F:TFirstObj;
S:TSecondObj
try
F:=TFirstObj.Create;
try
S:=TSecondObj.Create;
try
.....
?
← →
vuk © (2004-08-17 20:02) [1]
try
except
raise
end;
Это зачем? Перехватывать исключение только для перевозбуждения смысла нет.
← →
Sergey_Masloff (2004-08-17 20:12) [2]Ega23 © (17.08.04 19:57)
С двумя - как описано у тебя (то есть вложено try finally). Ну в смысле так делаю я - не претендуя на абс. истину
← →
YurikGL © (2004-08-17 23:08) [3]Я делаю так
try
...
except
on e:exception do
raise Exception.Create("Такая-то ошибка в процедуре такой-то."+#13+e.Message);
End;
ИМХО это сильно помогает при отладке "на месте" т.к. отражается вся цепочка исключений. Хотя мне было бы интересно выслушать мнение мастеров по поводу такого подхода
← →
Юрий Зотов © (2004-08-18 07:20) [4]> YurikGL © (17.08.04 23:08) [3]
> "Такая-то ошибка в процедуре такой-то."+#13+e.Message
Какая ошибка - это уже и так указано в e.Message. А в какой процедуре - это покажет отладчик. Поэтому при отладке на своей машине, под IDE вряд ли такой подход имеет смысл.
А вот на машине юзера, где программа работает сама по себе - да, сбор такой информации может быть очень полезным для последующего анализа и правки багов. Но тогда есть смысл не просто выдавать сообщения на экран, а еще писать их в лог. Потом юзер пересылает Вам это лог - и вперед.
> Ega23 © (17.08.04 19:57)
> Как правильно организовать создание, работу и освобождение
> объекта, а также передать "наверх" исключение, если такое
> возникнет.
Если подходить строго, то создавать и уничтожать каждый объект нужно в отдельном try-finally. И не надо никаких try-except, любое исключение и так передастся наверх (а все уже созданные объекты будут уничтожены, т.к. все finally для них все равно отработают).
Для N объектов "строгий" код должен быть таким:
var
Obj1, Obj2, ... ObjN: TMyObject;
begin
Obj1 := TMyObject.Create;
try
Obj2 := TMyObject.Create;
try
...
ObjN := TMyObject.Create;
try
...
finally
ObjN.Free
end
...
finally
Obj2.Free
end
finally
Obj1.Free
end
end;
← →
KSergey © (2004-08-18 08:31) [5]Делаю вложенные, хотя и напрягает, признаться
Иногда делаю так:obj1 := nil;
obj2 := nil;
obj3 := nil;
try
obj1 := TClass1.Create;
obj2 := TClass1.Create;
obj2 := TClass3.Create;
...
finally
obj1.Free;
obj2.Free;
obj3.Free;
end;
Я понимаю, что при исключениях в деструкторах такой код потенциально ошибочен, но когда надо создать 4-5 объектов, то делать уже такие вложения - лень...
← →
Skyle © (2004-08-18 08:42) [6]
> при исключениях в деструкторах
А я бы сказал, при исключениях в конструкторах..
← →
Ega23 © (2004-08-18 09:12) [7]Юрий Зотов © (18.08.04 07:20) [4]
А всё это обложить ещё ондим блоком try ... except, где raise с какой-то собственной информацией делать, так?
← →
Юрий Зотов © (2004-08-18 09:32) [8]> Ega23 © (18.08.04 09:12) [7]
Если требуется обработка ошибок прямо тут же, то можно и так. Если тут же не требуется, то и незачем - исключение передастся наверх и его можно обработать там. А можно и вообще не обрабатывать никаких исключений, тогда сработает дефолтный обработчик.
Смотря, что требуется, в общем.
← →
Ega23 © (2004-08-18 09:44) [9]Смотря, что требуется, в общем.
Требуется ведение журнала ошибок на клиенте. Т.е., в идеальном случае - передача exception в Application.OnException с пояснительным текстом - "что, где, когда". В идеале - вплоть до имени метода или функции.
← →
KSergey © (2004-08-18 09:48) [10]> [9] Ega23 © (18.08.04 09:44)
> пояснительным текстом - "что, где, когда". В идеале - вплоть
> до имени метода или функции.
Говорят (вот и тут недавно было) - JEDI, модуль debug
Но сам я еще не пробовал.
> [6] Skyle © (18.08.04 08:42)
>
> > при исключениях в деструкторах
>
> А я бы сказал, при исключениях в конструкторах..
При исключениях в конструкторах как раз проблем не будет. Перейдем на finally - и все пучком (для это обниливаем специально)
А вот если в деструкторе Obj1 исключение - тогда не разрушаем Obj2 и 3 вообще...
← →
Ega23 © (2004-08-18 09:53) [11]При исключениях в конструкторах как раз проблем не будет. Перейдем на finally - и все пучком (для это обниливаем специально)
Фишка в том, что в такой конструкции:
try
Obj:=TObj.Create
finally
Obj.Free
Ты получишь AV, если в конструкторе произошло исключение.
← →
KSergey © (2004-08-18 09:57) [12]> [11] Ega23 © (18.08.04 09:53)
> Фишка в том, что в такой конструкции:
> try
> Obj:=TObj.Create
>
> finally
> Obj.Free
>
> Ты получишь AV, если в конструкторе произошло исключение.
Почему???? Откуда исключение?
К тому же вы переврали мой код
Там принципиально были строки выше. Должно быть так:Obj := nil;
try
Obj:=TObj.Create
finally
Obj.Free
Тогда и причин для проблем я не вижу
Другое дело, что такой код для одиночного создаваемого объекта - бесмысслен.
← →
Ega23 © (2004-08-18 10:02) [13]Потому, что если в конструкторе произойдёт исключение - объект не будет создан, потом, провалившись на Free можно получить AV.
Я понял мысль, насчёт предварительного "обNILивания" указателя. Но есть ли гарантия, что после неудачной обработки конструктора, он по-прежнему останется nil?
← →
KSergey © (2004-08-18 10:03) [14]Разумеется есть. Полная.
← →
Skyle © (2004-08-18 10:18) [15]
> KSergey © (18.08.04 10:03)
Интересная конструкция.
Посыпаю голову пеплом...
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.035 c