Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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.063 c
4-1148380924
VitalZ
2006-05-23 14:42
2006.09.24
Unit для const THREAD_SUSPEND_RESUME


11-1132368516
-=Mike=-
2005-11-19 05:48
2006.09.24
Главная форма не точно отображает иконку программы


2-1157360717
com
2006-09-04 13:05
2006.09.24
Блокировщик виндувс


15-1157363915
umbra
2006-09-04 13:58
2006.09.24
Линукс. Как из tar-фрхива извлечь конкретный файл/каталог?


3-1153126192
nkolya
2006-07-17 12:49
2006.09.24
Синхронизация двух БД





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский