На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Кто берет ответственность за try? , в разных ОСях?
    я так и думал что 2 пример слишком абстрактный :) и для него найдется куча решений, как и для первого впрочем. Я хотел сказать что в блок __finally мы попадем до выхода из блока try и там можно сделать все что необходимо для корректного завершения блока try

    ExpandedWrap disabled
      //для файла который мы открыли:
      try{
        if( ReadHeader( fn ) != "Rar!" )return; //файл не закрываем!, исключений нет
        anyobject = ReadLine( 10 ); // допустим выбрасывает исключение
      } catch (...) {;}
      Цитата
      Sazabis, 29.01.04, 14:36

      //для файла который мы открыли:
      try{
      if( ReadHeader( fn ) != "Rar!" )return; //файл не закрываем!, исключений нет
      anyobject = ReadLine( 10 ); // допустим выбрасывает исключение
      } catch (...) {;}


      Если файл был открыт до блока try, то мы его можем спокойно закрыть после блока catch. __finaly тут ни к чему.
        я имею ввиду множественные выходы из функции. Тот же пример, после открытия файла, проверить его заголовок, свои там данные или не те. После открытия мы можем выйти как после того, как убедимся что файл не пригоден для дальнейшего чтения, так и после успешного считывания файла. В обоих случаях файл надо закрыть. Сразу предвижу ответ if( ReadHeader( fn ) != "Rar!" )throw ...; но если на выход надо скажем значение enum подавать то с catch это уже switch'и и гемор.
          Так, давай еще раз, по-порядку. При программировании на C++ правильной парадигмой считается парадигма "объявление ресурса есть инициализиация". Что это значит. Если ты объявляешь объект (например, ifstream), то выделение ресурсов для этого объекта производится в конструкторе (в общем случае), а деинициализация ресурсов - в деструкторе. Следуя этой парадигме мы получаем код, для которого блок __finaly не нужен, т. к. при выходе из области видимости переменной (выделенного ресурса) автоматически вызывается деструктор и производится деинициализация. Это справедливо равно как для выхода из метода, так и для выхода из блока try или любого другого фрагмента, ограниченного операторными скобками ({}). Таким образом, опасности блока __finaly заключается в следующем:
          1. Это не стандартная языковая конструкция. Таким образом, код получается непереносимым и не естественным для языка.
          2. Нет гарантии, что эта конструкция реализована правильно с точки зрения именно C++. Т. е. что производится корректное разрушение всех локальных объектов и т. п, т. к. корнями она уходит в С (от Microsoft).
          3. Использование этой конструкции имеет ряд ограничений. В частности, нельзя одновременно (в одном методе) использовать конструкции try/catch и try/__except/__finaly
          4. Использование этой конструкции противоречит идеалогии языка (см. первый абзац), и прививает плохой стиль.

          Приведенные тобою примеры с файлом не состоятельны по простой причне - если пользоваться std::ifstream или CFile, то необходимость блока __finaly отпадает сама собой, т. к. все необходимые действия по закрытия файла будут выполнены в деструкторах соответствующих классах. Вариант с FILE я не рассматриваю, т. к. это характерно для программирования на C, а не на С++.
            Цитата

            Но должен тебя предупредить - это считается плохим стилем


            А кстати, почему? если есть такая возможность в языке, то наверное, можно
            ее использовать. Дело в том, что я отлавливаю все ошибки руками, проверяю HRESULT-ы
            указатели на 0, ну и т.д., try я хочу использовать как верхний уровень безопасности,
            что ли. потому что бывает то всякое.
              Цитата
              AQL, 29.01.04, 15:49
              А кстати, почему?

              Потому что если все ошибки правильно обрабатываются, а вероятность SEH нулевая (т. е. нет ситуаций, которые моглибы привести, например, к AV), то catch (...) не нужен. Минус его еще в том, что он скрывает истинное место возникновения ошибки. Т. е. если у тебя есть catch (...) и (даже под дебагером) возникает, например, AV, то даже дебагер его не поймает.
                ну, это я по логам разберу, докудова исполнение дошло.
                  Цитата
                  AQL, 29.01.04, 12:49
                  если есть такая возможность в языке, то наверное, можно
                  ее использовать


                  Не путай понятий - обработка исключений как раз хороший ситль. Плохой стиль - один большой универсальный блок try/catch.Хороший стиль - ловить исключения в тех местах, где они могут возникнуть, а не на всем промежутке исполнения.

                  А как реализованно try/catch зависит от компилятора. Делфи например вызывает RaiseException из kernel32. Есть подозрение, что Builder может делать то же самое.
                    у меня как раз и возник вопрос по мотивам Билдера. Вроде в в исходниках были
                    try и catch, только все равно, когда драйвер устройства вставал криво -
                    типичное красное окошечко и все умирало. Мне показалось, что это не очень логично.
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0260 ]   [ 16 queries used ]   [ Generated: 3.05.24, 06:58 GMT ]