Во-первых, я хорошо понимаю, почему в C ++ нет конструкции «наконец»? но продолжительное обсуждение комментариев по другому вопросу, кажется, требует отдельного вопроса.
Помимо проблемы, finally
заключающейся в том, что в C # и Java в принципе может существовать только один раз (== 1) на область действия, и в одной области может быть несколько (== n) деструкторов C ++, я думаю, что это по сути одно и то же. (С некоторыми техническими отличиями.)
Однако другой пользователь утверждал :
... Я пытался сказать, что dtor по своей сути является инструментом для (Release sematics) и, наконец, по сути, инструментом для (Commit семантики). Если вы не понимаете, почему: подумайте, почему допустимо бросать исключения друг на друга в блоках finally, и почему это не относится к деструкторам. (В некотором смысле, это данные против контроля. Деструкторы предназначены для освобождения данных, наконец, для освобождения контроля. Они разные; к сожалению, C ++ связывает их вместе.)
Может кто-нибудь прояснить это?
источник
A
иB
. Если один поток выбрасывает, откатA's
транзакции не должен уничтожать ресурсы, выделенныеB
, например, - состояния потока не зависят друг от друга, а постоянная память, живущая в куче, не зависит от обоих. Однако, как правило, в C ++ память кучи все еще привязана к объектам в стеке.std::vector
объект может жить в стеке, но указывать на память в куче - и векторный объект (в стеке), и его содержимое (в куче) будут освобождены во время разматывания стека в этом случае, так как уничтожение вектора в стеке вызовет деструктор, который освобождает связанную память в куче (и аналогично уничтожает эти элементы кучи). Как правило, для обеспечения безопасности исключений большинство объектов C ++ живут в стеке, даже если они являются только ручками, указывающими на память в куче, автоматизируя процесс освобождения памяти кучи и стека при разматывании стека.Рад, что вы опубликовали это как вопрос. :)
Я пытался сказать, что деструкторы и
finally
концептуально разные:finally
для возврата звонящему ( контроль )Рассмотрим, скажем, этот гипотетический псевдокод:
finally
здесь полностью решается проблема управления, а не проблема управления ресурсами.Не имеет смысла делать это в деструкторе по разным причинам:
logfile.print
терпеть неудачу, тогда как разрушение (концептуально) не может потерпеть неудачуВот еще один пример, на этот раз как в Javascript:
В приведенном выше примере, опять же, нет ресурсов для освобождения.
На самом деле,
finally
блок получение внутренних ресурсов для достижения своей цели, которая потенциально может потерпеть неудачу. Следовательно, не имеет смысла использовать деструктор (если он был у Javascript).С другой стороны, в этом примере:
finally
разрушает ресурсb
. Это проблема с данными. Проблема не в том, чтобы вернуть контроль вызывающей стороне, а в том, чтобы избежать утечек ресурсов.Неудача не вариант, и никогда не должно происходить (концептуально).
Каждый выпуск
b
обязательно сопряжен с приобретением, и имеет смысл использовать RAII.Другими словами, просто потому, что вы можете использовать либо для симуляции, либо это не означает, что оба являются одной и той же проблемой, или что оба являются подходящими решениями для обеих проблем.
источник
finally
в основном используется для высвобождения ресурсов (не связанных с памятью), влияет на это?finally
.finally
предложении. Мировоззрение C ++ представило бы класс, который управляет этим «ресурсом» присваивания псевдоглобальной переменной. Какой концептуальный смысл это имеет? Но деструкторы - это молоток C ++ для требуемого выполнения кода конца блока.Ответ K3B действительно хорошо формулирует это:
Что касается «ресурсов», я хотел бы сослаться на Джона Калба: RAII должен означать «Ответственность за приобретение - это инициализация» .
В любом случае, что касается неявного и явного, это действительно так:
Я думаю, что это концептуальная часть ...
... теперь есть ИМХО некоторые интересные детали:
fault
блока для запуска кода, который должен выполняться только в случае исключительного выхода из области видимости.SCOPE_EXIT
,SCOPE_FAIL
иSCOPE_SUCCESS
в библиотеке глупостей . См. Андрей Александреску: Обработка ошибок в C ++ / Декларативный поток управления (проводится на NDC 2014 )Я также не думаю, что c'tor / d'tor нужно концептуально «приобретать» или «создавать» что-либо, кроме ответственности за запуск некоторого кода в деструкторе. Что, в конце концов, и делает: запустить некоторый код.
И хотя код в блоке finally, безусловно, может генерировать исключение, для меня недостаточно различия, чтобы сказать, что они концептуально отличаются от явных и неявных.
(Плюс, я совсем не уверен, что «хороший» код должен окончательно выбрасываться - возможно, это еще один вопрос сам по себе.)
источник
observer
примере, что бросать там было бы действительно плохой идеей.) Не стесняйтесь открывать чат, если вы хотите обсудить это дальше. Конечно, было весело думать о ваших аргументах. Приветствия.