Деструктор, который вызывает функцию, которая может выдать исключение в C++

Совершенно новое Мышление, Daniel Pink. Интересное взятие на будущем нашей промышленности.

я принимаю большинство людей, читающих, это уже прочитает книги наверху списка. Так, я предложу книгу, которая бросает различный взгляд на нашу промышленность.

сопроводительный текст http://www.danpink.com/images/wnm.jpg

10
задан Gal Goldman 27 July 2009 в 13:47
поделиться

4 ответа

Да, это законно. Исключение не должно экранировать из деструктора, но все, что происходит внутри деструктора или в функциях, которые он вызывает, зависит от вас.

(Технически, исключение также может исчезнуть из вызова деструктора. Если это происходит во время раскрутки стека из-за того, что было сгенерировано другое исключение, вызывается std :: terminate . Таким образом, это четко определено стандартом, но это действительно плохая идея.)

19
ответ дан 3 December 2019 в 18:00
поделиться

Вы можете найти эту страницу из C ++ FAQ Lite как информативную. Основной ответ - «не делай этого». Где именно вы планируете поймать это исключение? Что бы вы ни планировали сделать, когда поймаете это исключение, просто сделайте это с помощью вызова функции или чего-то еще (например, зарегистрируйте это или установите флаг для предупреждения пользователя или что-то еще). Выброс исключений из деструктора может привести к завершению всей вашей программы.

-1
ответ дан 3 December 2019 в 18:00
поделиться

Простой ответ, никогда не допускайте исключения из dtor!

Сложный ответ. Вы действительно получите результат, только если исключение ускользает от dtor, пока активно другое исключение. Обычно это происходит, когда вы уже раскручиваете стек из другого исключения, а рассматриваемый объект уничтожается. В этом случае, если исключение ускользает от dtor, вызывается std :: terminate , обратите внимание, что вы можете добавить свой собственный обработчик для std :: terminate , вызвав std: : set_terminate . Реализация по умолчанию std :: terminate заключается в вызове прерывания.

Чтобы еще больше усложнить ситуацию, большинство функций, которые хотят дать какие-либо гарантии своей безопасности исключений, в основном базовую гарантию или строгую гарантию, полагаются на базовые типы, чтобы они не добавляли их dtor *

Реальный вопрос в том, в каком состоянии будет ваша программа при возникновении этой ошибки? Как можно вылечиться? Куда обращаться с этим восстановлением? Вам нужно посмотреть на свой конкретный случай и решить эти проблемы. Иногда просто поймать исключение и проигнорировать его. В других случаях вам нужно поднять несколько красных флажков.

Итак, ответ таков: C ++ позволяет генерировать исключение в dtor, но вы никогда не должны позволять ему убегать.

* Здесь ' прочный и невысокий).

Основная гарантия заключается в том, что не удалось операции могут изменить состояние программы, но утечек не происходит объекты / модули по-прежнему разрушаемы и пригоден для использования в последовательном (но не обязательно предсказуемое) состояние.

Сильная гарантия включает транзакционная фиксация / откат семантика: гарантия неудачных операций состояние программы не меняется с по отношению к объектам оперирования. Это означает отсутствие побочных эффектов, влияющих на объекты, включая действительность или содержимое связанных вспомогательных объектов такие как итераторы, указывающие на контейнеры, которыми манипулируют.

Гарантия отсутствия высоты означает, что неудачных операций не будет. В операция не вызовет исключения.

0
ответ дан 3 December 2019 в 18:00
поделиться

Да.

В качестве примера посмотрите класс std :: fstream в стандартной библиотеке.

  • close () потенциально может вызвать исключение.
  • Деструктор может вызывать close (), но деструктор не генерирует (он принимает любые исключения).

Идея состоит в том, что если деструктор вызывает какие-либо методы, которые могут генерировать вызов, эти методы должны быть общедоступными. Таким образом, если пользователь вашего объекта хочет проверить исключения, он может использовать общедоступные методы и обработать исключение. Если они не заботятся об исключении, просто позвольте деструктору решить проблему.

Возвращаясь к примеру std :: fstream.

{
    std::fstream   text("Plop");
    // Load Text.

    // I don't care if the close fails.
    // So let the destructor handle it and discard exceptions
}



{
    // If this fails to write I should at least warn the user.
    // So in this case I will explicitly try and close it.
    try
    {
        std::ofstram    password("/etc/password");
        // Update the password file.

        password.close();
    }
    catch(...)
    {
          Message.ShowDialog("You failed to update the Password File");
    }
}
3
ответ дан 3 December 2019 в 18:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: