исключение выгоды указателем в C++

Я нашел, что существует три способа поймать исключение, каковы различия?

1) выгода значением;

2) выгода ссылкой;

3) выгода указателем;

Я только знаю, что выгода значением вызовет две копии объекта, выгода ссылкой вызовет ту. Таким образом как насчет выгоды указателем? Когда использовать выгоду указателем? Кроме того, для броска объекта я могу бросить указатель на объект как это?

class A {}

void f() {

  A *p = new A();
        throw p;


}
48
задан Gregory Pakosz 8 January 2010 в 00:06
поделиться

5 ответов

Рекомендуется бросать по значению и ловить по ссылке.

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

Если вы действительно считаете, что нужно бросать указатель, используйте умный указатель типа shared_ptr.

В любом случае, Херб Саттер и Алексей Александреску объясняют это очень хорошо в своей книге "Стандарты кодирования C++", которую я перефразировал.

Смотрите C++ Стандарты кодирования: Throw by Value, Catch by Reference.

.
79
ответ дан 26 November 2019 в 18:42
поделиться

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

Однако, некоторые библиотеки (Boost.Graph делает это, я полагаю) используют throw, чтобы передать обратно вызывающей функции возвращаемое значение; в такой ситуации возвращаемое значение может быть указателем, поэтому бросать указатель имеет смысл.

.
1
ответ дан 26 November 2019 в 18:42
поделиться

Поймать следует обычным правилам совместимости назначений, то есть если бросить значение, то можно поймать его как значение или ссылку, но не как указатель; если бросить указатель, то можно поймать его только как указатель (или ссылку на указатель...).

Но на самом деле бросать указатели не имеет смысла, это только вызовет головные боли в управлении памятью. Таким образом, следует, в общем случае, следовать правилу throw by value, catch by reference, как объяснил Григорий.

.
16
ответ дан 26 November 2019 в 18:42
поделиться

В MFC Microsoft используется перехват по указателю, но я думаю, что это было для совместимости с компилятором до того, как попытка перехвата была правильно реализована; изначально они использовали макросы TRY и CATCH для симуляции. Каждое исключение происходит из CException, который имеет метод определения необходимости удаления объекта.

Я бы не рекомендовал это для любого современного дизайна исключений. Поймать по ссылке - это путь.

4
ответ дан 26 November 2019 в 18:42
поделиться

Хотя можно бросать практически любой объект любого типа, в этом случае мало что (если вообще что-нибудь) можно получить. Динамическое выделение полезно в первую очередь тогда, когда объекту нужно время жизни, а не автоматическое выделение, т.е. вы хотите, чтобы время его жизни не зависело от нормальной области действия программы.

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

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

2
ответ дан 26 November 2019 в 18:42
поделиться
Другие вопросы по тегам:

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