Форум: "Прочее";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
ВнизПосле Delphi, не могу осмыслить обработку исключений в С++ Найти похожие ветки
← →
GuAV © (2006-09-05 18:16) [0]Кто её понимает и умеет пользоваться, просьба заглянуть сюда:
http://rsdn.ru/Forum/Message.aspx?mid=2092813&only=1
← →
default © (2006-09-05 18:20) [1]посмотрю попозже, правда я познавал исключения через C#
← →
ANB © (2006-09-05 18:20) [2]ИМХО.
Когда писал на билдере не сразу въехал, что по ретурну в блок finally выполнение не заходит (может я ошибаюсь ?).
← →
wicked © (2006-09-05 18:32) [3]1) хорошо бы использовать smart pointers для таких вещей - обьект будет освобождаться при выходе из области видимости не зависимо от того, было исключение или нет... использовать эти smart pointers лучше не стандартные (из STL), а из boost (www.boost.org)
2) по моему - лучше такого вообще не допускать, поскольку деструктор вызывать никто не будет. но тут могу ошибаться
← →
default © (2006-09-05 18:42) [4]1. а так?
__try
{
/* здесь могут быть выброшенны любые исключения */
...
if (something.IsWrong)
throw "error !";
...
/* ещё хотелось бы иметь возможность использовать return */
...
if (our_job.IsComplete)
return
...
throw "finally throw"; // чтобы гарантировано исполнился finally код в catch
}
__catch(ex)
{
delete obj; /* или DeleteObject(Pen) */ // finally код в catch
throw; // сохраняем исключение
}
← →
default © (2006-09-05 18:44) [5]ANB © (05.09.06 18:20) [2]
ошибаешься
← →
default © (2006-09-05 19:10) [6]2) точно не знаю, но думаю деструктор должен вызываться автоматом
ибо конструктор есть подготовка к работе объекта
если она не прошла успешно значит объект не готов к работе и нельзя возвращать ссылку на него во вне, память выделенная под объект перед вызовом конструктора также должна быть освобождена ибо объект фактически получился полуфабрикатом и не должен отяжелять свет божий своей полуфабрикованной сущностью:)
← →
default © (2006-09-05 19:18) [7]блин, вот с поправкой(во всём написанном мной синтаксисе не уверен, главное тебе логику в коде узрить)
1. а так?
__try
{
/* здесь могут быть выброшенны любые исключения */
...
if (something.IsWrong)
throw "error !";
...
/* ещё хотелось бы иметь возможность использовать return */
...
if (our_job.IsComplete)
return
...
throw "finally throw"; // чтобы гарантировано исполнился finally код в catch
}
__catch(ex e)
{
delete obj; /* или DeleteObject(Pen) */ // finally код в catch
if (e.message != "finally throw") throw; // сохраняем исключение если код
//остановился по реальной причине и продолжаем выполнение после catch
//если это было наше фиктивное исключение в конце try
}
← →
ANB © (2006-09-05 19:20) [8]
> default © (05.09.06 18:44) [5]
> ANB © (05.09.06 18:20) [2]
> ошибаешься
Дык вроде как отладчиком ходил. Впрочем, если я ошибался - это хорошо. Хоть одним геморром меньше.
← →
default © (2006-09-05 19:28) [9]ANB © (05.09.06 19:20) [8]
я с позиции логики сказал, что ошибаешься
с билдером дела не имел...если так как говоришь - то билдеру должно быть за такое стыдно:)
← →
guav © (2006-09-05 21:53) [10]
> я познавал исключения через C#
> [1] default © (05.09.06 18:20)
Аналогия с С# не подходит, т.к. в .NET всё по-другому:
1) в managed C++ есть finally
2) в managed C++ кроме деструкторов есть финализаторы, как этим всем счастьем пользоваться я пока не понял, поэтому вопрос про деструкторы не актуален.
> [3] wicked © (05.09.06 18:32)
1) похоже что smart pointers - единственно верное решение.
2) Ну да, не будет. Только нафига так сделано и какая от такого деструктора польза - непонятно. А насчёт исключений в конструкторе - выделение памяти или ресурса в конструкторе вполне может быть, поэтому исключения не исключены.
[7] default ©
> throw "finally throw"; // чтобы гарантировано исполнился
> finally код в catch
Жестоко.
Разумеется, это будет работать (для исключений, не для return), но оверхед на создание и обработку исключения (в нормальной ситуации, где иначе бы исключение не поднималось) несоизмеремо больше оверхеда на finally.
Пунтк 2 на данный момент - то что мне больше всего не нравится в С++.
← →
default © (2006-09-05 22:19) [11]guav © (05.09.06 21:53) [10]
"Жестоко.
Разумеется, это будет работать (для исключений, не для return), но оверхед на создание и обработку исключения (в нормальной ситуации, где иначе бы исключение не поднималось) несоизмеремо больше оверхеда на finally."
ну можно финализацию обернуть в функцию, а вместо return писать
{final_func(...); return} но это всё изврат безусловно
__try
{
/* здесь могут быть выброшенны любые исключения */
...
if (something.IsWrong)
throw "error !";
...
/* ещё хотелось бы иметь возможность использовать return */
...
if (our_job.IsComplete)
return
...
final_func(...);
}
__catch(ex)
{
final_func(...);
throw;
}
← →
default © (2006-09-06 01:02) [12]guav © (05.09.06 21:53) [10]
"2) Ну да, не будет. Только нафига так сделано и какая от такого деструктора польза - непонятно. А насчёт исключений в конструкторе - выделение памяти или ресурса в конструкторе вполне может быть, поэтому исключения не исключены."
я тебя не очень понимаю
деструкторы выполняются для объектов у которых конструктор сработал успешно
если тебе надо в конструкторе гарантировать выполнение некоторой деинициализации при исключении(даже возможно непредвиденном), так почему бы не охватить весь код конструктора в try catch?
← →
default © (2006-09-06 01:06) [13]guav © (05.09.06 21:53) [10]
"2) в managed C++ кроме деструкторов есть финализаторы, как этим всем счастьем "
деструкторы в управляемом коде несколько иная штука, только название осталось да синтаксис:)
у тебя книжка, как я могу догадываться, в которой по ходу изучения C++ делаются отступления к MC++?
← →
guav © (2006-09-06 01:18) [14]> [12] default © (06.09.06 01:02)
Просто кажется ненормальным то что если в конструкторе может возникать исключения, то когда я уже предусмотрел деструктор, мне ещё приходится рассматривать исключения в конструкторе отдельно.
Ну да, всего лишь добавятся несколько строчек кода (явно ловим исключение, явно вызываем деструкор, поднимаем исключение обратно). Вопрос в том, почему не сделано это автоматом, и на какое применение расчитаны деструкторы в С++ при их таком поведении.
← →
guav © (2006-09-06 01:23) [15]> у тебя книжка, как я могу догадываться, в которой по ходу
> изучения C++ делаются отступления к MC++?
ага.
хотя уже решил найти другую - только про native С++ и более "продвинутую", чтобы такие вопросы не задавать.
не посоветуешь ?
← →
Аноним2000 (2006-09-06 01:24) [16]
> точно не знаю, но думаю деструктор должен вызываться автоматом
> ибо конструктор есть подготовка к работе объекта
> если она не прошла успешно значит объект не готов к работе
> и нельзя возвращать ссылку на него во вне, память выделенная
> под объект перед вызовом конструктора также должна быть
> освобождена ибо объект фактически получился полуфабрикатом
> и не должен отяжелять свет божий своей полуфабрикованной
> сущностью:)
Авторитетно заявляю, что если бросить С++ исключение в конструкторе объекта, этого объекта деструктор вызываться не будет. Но для членов класса, прошедших инициализацию и родительских классов деструктор вызван будет.
Отсюда следует решение: пользоваться стратегией "выделение ресурса (памяти, открытие файла, etc) - есть инициализация"
1 ресурс - 1 инициализация
использование STL, boost::shared_ptr, облегчает эту задачу, прежде всего работу с памятью
← →
default © (2006-09-06 01:39) [17]guav © (06.09.06 01:18) [14]
в C# если исключение необработанное вызвано в конструкторе класса, то таки финализатор(если он есть) вызывается когда объект становится мусором и сборщик мусора его подбирает(а подобрать он его может ой как не скоро, но можно сделать принудительный подбор, но это не рекомендуется, тем более подбираться при этом будет и другой мусор, что сказывается на производительности)
то есть нечто похожее на желаемое тебе есть
кстати, интересно, в C# если я в конструкторе ссылку на созданный объект где-нибудь сохраню и возникнет необработанное исключение я могу использовать этот объект извне(по сохранённой ссылке на него) ибо объект не становится мусором пока на него хоть есть одна активная ссылка в коде
guav © (06.09.06 01:23) [15]
не посоветую, я C# учу
а ты C++ направленно учишь? то есть работать с применением его собираешься? вроде щас иностранных контор с требованием C# и пр развелось
← →
default © (2006-09-06 01:44) [18]Аноним2000 (06.09.06 01:24) [16]
спасибо, понятно
← →
guav © (2006-09-06 02:03) [19]> 1 ресурс - 1 инициализация
т.е. если мне нужно два ресурса в одном классе, то мне нужно три класса - один для первого ресурса, другой для второго, и третий это тот который мне нужен ?
> а ты C++ направленно учишь? то есть работать с применением
> его собираешься?
Скажем так, кое-где востребованы моя специальность + с++ . Это не там где я скорее всего буду работать, но раз у меня всё равно есть способность программировать (надеюсь), стоит изучить что-то потенциально полезное.
Сам программером работаешь ?
← →
default © (2006-09-06 02:05) [20]guav © (06.09.06 02:03) [19]
учусь пока, целенаправленно
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.055 c