Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > В чем смысл __finnaly?


Автор: HappyLife 30.11.2007, 11:49
Доброго времени суток уважаемые форумчане.
Объясните пожалуйста В чем заключается глубокий филосовский смысл в ключевом слове __finally
Вот два разных кода.
Код
try
{
    throw int(0);
}
catch(int & i)
{
    error();
}

Sleep(1); // Этот код всегда будет.

И этот.
Код
try
{
    try
    {
        throw int(0);
    }
    catch(int &i)
    {
        error()
    }
}
__finally
{
    Sleep(1); // Этот код всегда будет.
}

Результат один и тот же.

Автор: volvo877 30.11.2007, 12:03
Help-ы не читаешь демонстративно?

Цитата(CodeGear Help)

bcc32 includes extensions to the C++ language that let it use finally blocks as well. Like exception handlers, a finally block must appear directly after the try block, but it is introduced by the__finally keyword instead of catch.



Автор: SenkraD 30.11.2007, 12:12
[offtop]
volvo877, у меня такое впечатление складывается, что люди иногда
(местами даже очень) зразу лезут на форум задавать вопросы, несмотря в справку,
 неища в гугле или на самом форуме, на самые примитивые темы и начисто игнорят
пункты 1 и 2 с правил форума
[/offtop]

Автор: Vyacheslav 30.11.2007, 14:34
Цитата(HappyLife @  30.11.2007,  11:49 Найти цитируемый пост)
Результат один и тот же.

Естественно тот же, поскольку  таким образом подобран пример. 
Для _finally нет работы если иcходить из того, что в любом случае  обработка исключения будет проводиться по месту.
Вся проблема в том, что такой взгляд весьма своеобразен и пропагандируется  Microsoft.  Если же предположить, что обработка исключения должна производится извне ( например есть централизованный обработчик ошибок, то твой код будет выглядеть следующим образом
Код

try
{
    throw 0;
}
catch(int & i)
{
    Sleep(1); //корректно завершили
   throw; //  дальнейшее продолжение алгоритма не имеет смысла.  Обработка самой ошибки будет сделана выше 
             //централизованно для всего приложения
}

Sleep(1); // Этот код всегда будет.




и

Код

try
{
         throw 0;
 }
__finally
{
    Sleep(1); // Этот код всегда будет.
}



Правда в С++ можно  относительно легко обойтись без __finally используя принцип  гардов( GUARD). Если ситуация со Sleep встречается довольно часто,  то может быть применено решение
Код

struct TGuardSleep
{
    ~TGuardSleep(){  Sleep(1); }
};

В результате получим
Код

{
   TGuardSleep guardSleep;
   throw 0;
}









Автор: HappyLife 30.11.2007, 14:46
Vyacheslav, 
Спасибо вам огромнейшее.

Автор: ksili 4.12.2007, 14:16
Я читал где-то статью про структурную обработку исключений (SEH). А может это была и глава из книги. Так вот про __finally там говорилось, что оно для более удобной финализации функций. То есть допустим в функции есть такие действия, которые должны быть обязательно выполнены, вне зависимости от корректности завершения функции. Такими дйствиями могут быть например освобождение выделенной в начале функции памяти или запись в лог. Проблема в том, что в фукции может быть много return'ов. Так вот, чтобы не писать так:
Код

a = new ....
b = new ....
c = new ....

.........

if(...)
    {
      delete a;
      delete b;
      delete c;
      return;
    }
....
if(...)
    {
      delete a;
      delete b;
      delete c;
      return;
    }
.....
if(...)
    {
      delete a;
      delete b;
      delete c;
      return;
    }
......
}

Можно воспользоваться __finally:
Код

a = new ....
b = new ....
c = new ....

.........

try
   {
    if(...)   return;
....
    if(...)   return;
.....
    if(...)   return;
...
    }
__finally
    {
      delete a;
      delete b;
      delete c;
    }
}

То есть запись получается короче, и получаем 100% уверенность, что память освободится. Это можно использовать даже не для обработки исключений.

Автор: Vyacheslav 5.12.2007, 14:22
Цитата(ksili @  4.12.2007,  14:16 Найти цитируемый пост)
Можно воспользоваться __finally:


А можно воспользовать auto_ptr или другими подобными конcтрукциями. Поэтому спор о целесобразности  __finally попрежнему  стоит на повестке дня smile 

Автор: Lazin 5.12.2007, 14:47
я где-то читал что лучше не смешивать использование обработки исключений в стили С++ (try catch) и расширения M$ (_try _except _finally).
В программе на С++ все исключения должны обрабатываться как С++ исключения.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)