В C++, там различие между “броском” и “броском исключая”?

Не недокументированный

любезность RowNumber Itzik Ben-Gan http://www.sqlmag.com/article/articleid/97675/sql_server_blog_97675.html

УСТАНАВЛИВАЕТ XACT_ABORT НА откате все на ошибке для транзакций

, весь _ SP полезен, просто просматривают книги онлайн

сочетания клавиш, которые я использую все время в студии управления, которую F6 - переключают между результатами и запрашивают Alt+X или F5-выполненный выделенный текст в запросе, если ничто не выбрано, работает, все окно Alt+T и Alt+D - приводит к тексту или сетке соответственно

18
задан Community 23 May 2017 в 12:34
поделиться

8 ответов

throw; повторно генерирует тот же объект исключения, который он поймал, а throw ex; генерирует новое исключение. Это не имеет значения, кроме причин производительности создания нового объекта исключения. Если у вас есть иерархия исключений, в которой есть другие классы исключений, производные от класса MyException , и при генерации исключения вы выполнили выброс throw DerivedClassException; его можно поймать с помощью ловушки (MyException &) . Теперь, если вы измените этот пойманный объект исключения и повторно выбросите его, используя throw; , тип объекта исключения по-прежнему будет DerivedClassException . Если вы выполните throw Ex; , произойдет разрезание объекта, и новое исключение будет иметь тип MyException .

32
ответ дан 30 November 2019 в 05:47
поделиться

[ C ++ FAQ Lite § 17.9 ] Что означает ; (без объекта исключения после ключевого слова throw )? Где мне его использовать?

Вы можете увидеть примерно такой код:

 class MyException {
общественность:
 ...
 void addInfo (const std :: string & info);
 ...
};

void f ()
{
 пытаться {
 ...
 }
 catch (MyException & e) {
 e.addInfo ("f () не удалось");
 бросить;
 }
}

В этом примере оператор throw; означает «повторно выбросить текущее исключение». Здесь функция перехватила исключение (по неконстантной ссылке), изменила исключение (добавив к нему информацию), а затем повторно выбросила исключение. Эту идиому можно использовать для реализации простой формы трассировки стека, добавив соответствующие предложения catch в важные функции вашей программы.

Другой идиомой повторного выброса является «диспетчер исключений»:

 void handleException ()
{
 пытаться {
 бросить;
 }
 catch (MyException & e) {
 ... код для обработки MyException ...
 }
 catch (YourException & e) {
 ... код для обработки исключения YourException ...
 }
}

void f ()
{
 пытаться {
 ... что-то, что может бросить ...
 }
 улов (...) {
 handleException ();
 }
}

Эта идиома позволяет повторно использовать одну функцию ( handleException () ) для обработки исключений в ряде других функций.

[ C ++ FAQ Lite § 17.11 ] Когда я выброшу этот объект, сколько раз он будет скопирован?

Зависит. Может быть «ноль».

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

( отредактировано для большей ясности в том, что я считал очевидным ... )

catch (MyException & ex) {throw ex; } может копировать ex со всеми вытекающими из этого проблемами; catch (MyException & ex) {бросить; } не может.

14
ответ дан 30 November 2019 в 05:47
поделиться

Вы можете использовать форму throw; с catch (...) (то есть это единственный способ перебросить, если вы поймали поймать (...)).

6
ответ дан 30 November 2019 в 05:47
поделиться

Есть большая разница. Я написал об этом в своем блоге по адресу: https://cpptalk.wordpress.com/2009/08/23/nuances-of-exception-rethrow/

Приглашаем вас взглянуть

3
ответ дан 30 November 2019 в 05:47
поделиться

throw ex создаст еще одну копию и не рекомендуется использовать throw только для выброса текущего объекта исключения.

2
ответ дан 30 November 2019 в 05:47
поделиться

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

2
ответ дан 30 November 2019 в 05:47
поделиться

Кроме того, поскольку это иногда вызывает путаницу, простой выброс ; вне контекста обработки исключений прервет выполнение программы.

1
ответ дан 30 November 2019 в 05:47
поделиться

Если у вас есть иерархия исключений, throw ex может вырезать ваше исключение, а throw не будет. Например:

#include <iostream> 
#include <string> 

using namespace std; 

struct base 
{ 
  virtual string who() {return "base";} 
}; 

struct derived : public base 
{ 
  string who() {return "derived";} 
}; 

int main() { 
  try { 
    try { 
      throw derived(); // throws a 'derived'
    }  
    catch (base& ex)  
    { 
      throw ex; // slices 'derived' object to be a 'base' object
    } 
  } 
  catch (base& ex) 
  { 
    cout<<ex.who()<<endl; // prints 'base'
  } 
} 

Измените throw ex на просто throw , и вы получите результат , производный , что вы, вероятно, ожидали получить.

13
ответ дан 30 November 2019 в 05:47
поделиться
Другие вопросы по тегам:

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