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

Вниз

После 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.028 c
15-1156343106
TUser
2006-08-23 18:25
2006.09.24
Каковы причины Первой Мировой Войны?


1-1155706859
DelphiLexx
2006-08-16 09:40
2006.09.24
Как рисунок c Canvas a на другой Canvas


15-1157607635
Иксик
2006-09-07 09:40
2006.09.24
Наши люди :)


2-1157650308
ZV
2006-09-07 21:31
2006.09.24
СОМ port


15-1156947353
Pazitron_Brain
2006-08-30 18:15
2006.09.24
Посоветуйте бесплатный хостинг