Форум: "Прочее";
Текущий архив: 2009.05.24;
Скачать: [xml.tar.bz2];
ВнизRe-raise исключений Найти похожие ветки
← →
It's not me (2009-03-18 13:35) [0]При выполнении конструктора некоего класса может произойти исключение номер 1.
Класс пытается выполнять некие действия, которые также могут привести к исключению номер 2. Данное исключение номер 2 обрабатывается нормально и предсказуемо. Но как бы отменить создание объекта по исключению номер 1?
То есть:constructor TMy.Create;
begin
try
<работаем работаем работаем>
except on E1:Exception do
try
<Пытаемся исправить ситуацию>;
except on E2:Exception do
<не получилось...>
<как re-raise"нуть E1?>
end;
end;
end;
← →
It's not me (2009-03-18 13:39) [1]Можно, конечно, просто сгенерировать abort. Но это как последний вариант.
Хотелось бы, чтобы код, создающий данный класс, имел информацию о том исключении, которое привело к невозможности создания класса.
← →
Palladin © (2009-03-18 13:39) [2]Raise;
← →
Palladin © (2009-03-18 13:41) [3]хотя вру... конструкция дикая...
зачем пытаться исправлять ситуацию в блоке except ?
← →
Empleado © (2009-03-18 13:43) [4]raise E1.Create?
← →
test © (2009-03-18 13:51) [5]Что то никаких идей кроме
FreeAndNil(Self)
но помойму это бред.
← →
Плохиш © (2009-03-18 14:01) [6]raise E1;
← →
It's not me (2009-03-18 14:15) [7]
> хотя вру... конструкция дикая...
предложи лучше
> зачем пытаться исправлять ситуацию в блоке except ?
хороший вопрос. А зачем вообще пытаться исправлять ошибки? имхо, затем, чтобы обойти возникшую проблему для продолжения нормального выполнения работы.
Это называется отказоустойчивость.
> Что то никаких идей кроме
> FreeAndNil(Self)
> но помойму это бред.
это действительно бред. Ты уже который раз пытаешься отвечать на вопрос при том, что тебе не хватает знаний даже понять этот вопрос.
Поизучай поведение дельфи, когда в конструкторе возникает необработанное исключение.
> raise E1.Create?
ты меня спрашиваешь? Я не знаю... )))
> raise E1;
так можно делать, это нормально?
Спасибо!
← →
Palladin © (2009-03-18 14:21) [8]constructor TMy.Create;
var
e1e:Exception;
begin
try
<работаем работаем работаем>
e1e:=Nil;
except on E1:Exception do e1e:=e1;
end;
If e1e<>Nil Then
try
<Пытаемся исправить ситуацию>;
e1e:=Nil;
except
end;
If e1e<>Nil Then Raise e1e;
end;
← →
Сергей М. © (2009-03-18 14:36) [9]
> It"s not me (18.03.09 13:35)
Как-то так:var
exptobj: Exception;
..
try
<работаем работаем работаем>
except on E1:Exception do
begin
exptobj := Exception(AcquireExceptionObject);
try
<Пытаемся исправить ситуацию>;
ReleaseExceptionObject;
except on E2:Exception do
<не получилось...>
raise excptobj;
end;
end;
end;
← →
test © (2009-03-18 14:43) [10]It"s not me (18.03.09 14:15) [7]
Извени великий учитель не признал, ты просто оставь пустые try except и все сам же обьяснял.
← →
It's not me (2009-03-18 14:55) [11]Palladin, абсолютно не понял, чем конструкция лучше. Ты просто ввел лишнюю переменную, удлинил код и убрал вложенность кода. А смысл?
Было:constructor TMy.Create;
begin
try
<работаем работаем работаем>
except on E1:Exception do
try
<Пытаемся исправить ситуацию>;
except Raise E1;
end;
end;
end;
стало:constructor TMy.Create;
var
e1e:Exception;
begin
try
<работаем работаем работаем>
e1e:=Nil;
except on E1:Exception do e1e:=e1;
end;
If e1e<>Nil Then
try
<Пытаемся исправить ситуацию>;
e1e:=Nil;
except
end;
If e1e<>Nil Then Raise e1e;
end;
ты считаешь твой код читабельнее? Хз, чем оперировать постоянно с e1e, мне читабельнее кажется мой код.
← →
Palladin © (2009-03-18 15:00) [12]
> It"s not me (18.03.09 14:55) [11]
Я тебе ничего не навязываю. Дело лично твое.
← →
It's not me (2009-03-18 15:00) [13]
> Как-то так:
ммм... А чем плох код:constructor TMy.Create;
begin
try
<работаем работаем работаем>
except on E1:Exception do
try
<Пытаемся исправить ситуацию>;
except Raise E1;
end;
end;
end;
?
← →
It's not me (2009-03-18 15:02) [14]
> Я тебе ничего не навязываю. Дело лично твое.
дык и я тебе ничего не навязываю. Ты предложил альтернативный стиль написания одного и того же по функциональности кода. Я высказал мнение, что мой вариант мне кажется более компактным и более читабельным. Вот и все )
← →
Сергей М. © (2009-03-18 15:02) [15]
> мне читабельнее кажется мой код
Если уж на то пошло, то в твоем варианте тоже требухи ненужной хватает - E1 и E2 совершенно лишние:var
exptobj: Exception;
..
try
<работаем работаем работаем>
except on Exception do
begin
exptobj := AcquireExceptionObject;
try
<Пытаемся исправить ситуацию>;
ReleaseExceptionObject;
except on Exception do
<не получилось...>
raise excptobj;
end;
end;
end;
← →
test © (2009-03-18 15:03) [16]Сергей М. © (18.03.09 15:02) [15]
Что скажешь?
type
TMy=class
private
constructor Create;
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function GetMy():TMy;
var
Form1: TForm1;
implementation
uses ConvUtils;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
x:TMy;
begin
x := GetMy;
try
if x = nil then
Memo1.Lines.add("nil");
except
on e:Exception do
Memo1.Lines.add(e.Message);
end;
end;
{ TMy }
constructor TMy.Create;
begin
inherited Create;
end;
function GetMy: TMy;
begin
try
Result := TMy.Create;
RaiseConversionError("Âñå ïëîõî");
except
Result := nil;
end;
end;
end.
← →
Сергей М. © (2009-03-18 15:15) [17]
> test © (18.03.09 15:03) [16]
Скажу - лажа.
Мемлик гарантирован.
← →
It's not me (2009-03-18 15:35) [18]
> Если уж на то пошло, то в твоем варианте тоже требухи ненужной
> хватает - E1 и E2 совершенно лишние:
в моем варианте [13] требухи в виде E2 просто нету.
E1 есть, но с тем же успехом я могу сказать, что у тебя лишнее объявление:var
exptobj: Exception;
В твоем варианте явное объявление exptobj. А в моем варианте неявное объявление E1. Монописуально, ты так не считаешь? )))
test, перестань смешить людей. Ну ты реально написал бред в видеFreeAndNil(Self)
в конструкторе. Понятно, что тем самым ты хотел освободить занятую экземпляром класса к тому времени память.
Но ты, видимо, не знаешь, что при возникновении необработанного исключения в конструкторе - дельфи автоматически очищает выделенную к тому времени память и создание объекта отменяется. Поэтому вместо FreeAndNil(Self) можно просто написать Abort; и его не обработать.
Но это в вопросе даже не спрашивалось, этот факт просто подразумевался. Вопрос был совершенно о другом, а не как остановить создание объекта.
Вместо того, чтобы признать свои пробелы в знаниях, ты решил продолжить финтить ушами. Почитай лучше литературу, всяко полезнее.
← →
Сергей М. © (2009-03-18 16:15) [19]
> в моем варианте [13]
Зато в [0] есть.
А то что ты в [13] "доточил" свой же код в [0], то в чем тогда был смысл топикстарта ?
← →
Сергей М. © (2009-03-18 16:20) [20]
> При выполнении конструктора некоего класса
А фиолетово в конструкоре это происходит или не в конструкторе.
Ежу понятно что исключение, выброшенное в конструкторе (неважно какое и какого уровня вложенности обработки), приведет к несозданию объекта.
Ты для кого, спрашивается, делал это никому не нужное уточнение, г-н агрессивный ?)
← →
test © (2009-03-18 16:27) [21]It"s not me (18.03.09 15:35) [18]
С тобой никто не говорит ты все точки над и расставил, форум/ветка не твоя собственность так что, я тебя игнорю ты меня идилия.
Сергей М. © (18.03.09 16:15) [19]
Буду думать.))
← →
Сергей М. © (2009-03-18 16:35) [22]
> test © (18.03.09 16:27) [21]
> Буду думать
А что тут думать ?
Тут пилить надо)
function GetMy: TMy;
begin
try
Result := TMy.Create; //<-- предположим, тут объект успешно создан (ресурсы под него выделены)
RaiseConversionError("Âñå ïëîõî"); //<-- хрясь исключение !
except
Result := nil; <-- попадаем сюда, нилим результат и преспокойненько возвращаем управление вызывающему коду
end;
end;
// а вот собссно и он
procedure TForm1.Button1Click(Sender: TObject);
var
x:TMy;
begin
x := GetMy; //<-- получили нил
try
if x = nil then //бесполезная проверка, ибо GetMy у тебя всегда вернет нил
Memo1.Lines.add("nil"); //вряд ли это вызовет исключение
except
// сюда никогда не попадем
on e:Exception do
Memo1.Lines.add(e.Message);
end;
end;
← →
It's not me (2009-03-18 17:02) [23]
> Ты для кого, спрашивается, делал это никому не нужное уточнение
для Test"а, который как ты не заметил в посте номер [5] предложил в конструкторе писать FreeAndNil(Self).
А за выдачу сугубо личного мнения о "ненужности" уточнения за общественное - зачот. Характеризует )
← →
Сергей М. © (2009-03-18 17:15) [24]
> для Test"а
Test (С) в топикстарте никаким боком еще не фигурировал, а упоминание конструктора было тобой сделано уже там, так что не гони уже пургу)
> о "ненужности" уточнения
А оно действительно ненужное)
По сути ты затянул бодягу про совсем другое - как по вложенном перехватчике исключения возбудить исключение, перехваченное уровнем выше.
← →
Игорь Шевченко © (2009-03-18 17:31) [25]Питер, а ты вообще нафига сюда ходишь ? У тебя проблемы с общением, или еще с чем ?
Просто интересно...
← →
Anatoly Podgoretsky © (2009-03-18 19:44) [26]> It"s not me (18.03.2009 14:15:07) [7]
> А зачем вообще пытаться исправлять ошибки?
Правильно незачем, вот я и не исправляю.
← →
vuk © (2009-03-18 20:59) [27]Непонятная тема. Исклиючния в конструкторе обрабатывать нафиг не надо. Деструктор нужно писать так, чтобы он отрабатывал нормально даже тогда, когда конструктор осыпался по исключению. Вот и весь сказ. Собственно, это в справке написано всё.
← →
Сергей М. © (2009-03-18 21:14) [28]
> vuk © (18.03.09 20:59) [27]
Конструктор тут вообще ни причем, это он его всуе приплёл для "пущей важности проблемы".
Та же самая "проблема" с теми же самыми решениями точно так же применима и к обычной регулярной процедуре или ф-ции и к любому другому методу объекта.
← →
vuk © (2009-03-18 21:24) [29]А не надо всуе приплетать, т.к. ситуации разные получаются. :)
← →
Сергей М. © (2009-03-18 21:44) [30]
> vuk © (18.03.09 21:24) [29]
Ну вот загорелось ему рерайзить E1 в момент обработки E2 !
Ну и пусть себе рерайзит, благо проблема высосана из пальца.
> как бы отменить создание объекта по исключению номер 1?
Да хоть по номер столохматому !
Цитирую самого себя:
> Ежу понятно что исключение, выброшенное в конструкторе (неважно
> какое и какого уровня вложенности обработки), приведет к
> несозданию объекта
Но автор явно не ёж, потому как шибко беспокоится, что объект останется неразрушенным, если какое-то там исключение (по барабану какое) в конструкторе не будет там же и погашено.
← →
It's not me (2009-03-18 23:09) [31]
> Исклиючния в конструкторе обрабатывать нафиг не надо. Деструктор
> нужно писать так, чтобы он отрабатывал нормально даже тогда,
> когда конструктор осыпался по исключению. Вот и весь сказ.
> Собственно, это в справке написано всё
не догнал...
Если конструктор осыпался по исключению, то создающий экземпляр класса внешний код просто не получит ссылку на этот собственно экземпляр класса. Соответственно, никак и деструктор не сможет вызвать (разве что над nil, а это уже разруливает free)... Поясни плиз.
← →
It's not me (2009-03-18 23:13) [32]
> потому как шибко беспокоится, что объект останется неразрушенным
опять ты, г-н Гений, решаешь за меня о чем я беспокоюсь.
Ежу понятно, что любое исключение в конструкторе приведет к несозданию объекта. Беспокоюсь я не об этом, а о том, какие исключение выплюнется во внешний код при несоздании объекта. И в моем случае гораздо лучше выплевывать исключение по E1, которое реально и привело к невозможности создать объект, чем исключение E2, которое лишь побочка от попыток разрулить исключение E1 и может только запутать внешний код, если он обрабатывает исключения.
← →
It's not me (2009-03-18 23:16) [33]
> Если конструктор осыпался по исключению, то создающий экземпляр
> класса внешний код просто не получит ссылку на этот собственно
> экземпляр класса
ну имеется в виду, конечно, классическое создание объекта через TClassType.Create, а не махинации со всякими InitInstance.
← →
Плохиш © (2009-03-18 23:22) [34]
> It"s not me (18.03.09 23:09) [31]
>
>
> Если конструктор осыпался по исключению, то создающий экземпляр
> класса внешний код просто не получит ссылку на этот собственно
> экземпляр класса. Соответственно, никак и деструктор не
> сможет вызвать (разве что над nil, а это уже разруливает
> free)... Поясни плиз.
>
Ты бы почитал для начала чего...
← →
Германн © (2009-03-19 00:07) [35]
> благо проблема высосана из пальца.
>
+1
← →
Palladin © (2009-03-19 00:13) [36]
> It"s not me (18.03.09 23:09) [31]
если в конструкторе класса возникает исключение, то автоматически вызывается деструктор конструируемого объекта
и кстати для этих случаев придуман free
← →
Palladin © (2009-03-19 00:19) [37]а по поводу ловли исключения именно на этапе создания (не в самом конструкторе, а именно выше уровнем) я знаю только один класс где иногда нужно это делать - TFileStream
← →
vuk © (2009-03-19 00:35) [38]to It"s not me (18.03.09 23:09) [31]:
>Поясни плиз.
Что пояснять-то? При обломе в конструкторе деструктор вызывается автоматически. Проверяется элементарно. Отладчик в помощь. И справку читать про конструкторы и деструкторы.
← →
Сергей М. © (2009-03-19 08:31) [39]
> Беспокоюсь я не об этом, а о том, какие исключение выплюнется
> во внешний код
Какое выплюнешь, такое и выплюнется.
Но это твое
> как бы отменить создание объекта
не имеет к выплевыванию какого-то конкретно интересующего тебя исключения ни малейшего отношения.
← →
Rouse_ © (2009-03-19 09:58) [40]А я бы переписал всю конструкцию...
ну или уволил бы разработчика, умудрившегося написать код, который два раза подряд может влететь в исключение...
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2009.05.24;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.007 c