Throw c что это
Обычно система сама генерирует исключения при определенных ситуациях, например, при делении числа на ноль. Но язык C# также позволяет генерировать исключения вручную с помощью оператора throw . То есть с помощью этого оператора мы сами можем создать исключение и вызвать его в процессе выполнения.
Например, в нашей программе происходит ввод имени пользователя, и мы хотим, чтобы, если длина имени меньше 2 символов, то возникало исключение:
После оператора throw указывается объект исключения, через конструктор которого мы можем передать сообщение об ошибке. Естественно вместо типа Exception мы можем использовать объект любого другого типа исключений.
Затем в блоке catch сгенерированное нами исключение будет обработано.
Подобным образом мы можем генерировать исключения в любом месте программы. Но существует также и другая форма использования оператора throw, когда после данного оператора не указывается объект исключения. В подобном виде оператор throw может использоваться только в блоке catch:
В данном случае при вводе имени с длиной меньше 2 символов возникнет исключение, которое будет обработано внутренним блоком catch. Однако поскольку в этом блоке используется оператор throw, то исключение будет передано дальше внешнему блоку catch, который получит то же самое исключение и выведет то же самое сообщение на консоль.
20.2 – Основы обработки исключений
В предыдущем уроке о необходимости исключений мы говорили о том, как использование кодов возврата приводит к смешиванию порядка выполнения программы и порядка обработки ошибок, ограничивая и то и другое. Исключения в C++ реализуются с использованием трех ключевых слов, работающих вместе: throw , try и catch .
Выбрасывание исключений
В реальной жизни, чтобы отметить, что произошли определенные события, мы постоянно используем сигналы. Например, во время американского футбола, если игрок совершил фол, судья бросает флаг на землю и дает свисток об остановке игры. Затем назначается и исполняется наказание. Как только наказание снято, игра, как правило, возобновляется в обычном режиме.
В C++ для сигнализации о том, что произошло исключение или ошибка (пример с выбрасыванием флага штрафа) используется инструкция throw . Сигнализация о возникновении исключения также обычно называется генерацией или выбрасыванием исключения.
Чтобы использовать инструкцию throw , просто используйте ключевое слово throw , за которым следует значение любого типа данных, который вы хотите использовать, чтобы сигнализировать о возникновении ошибки. Обычно это значение будет кодом ошибки, описанием проблемы или пользовательским классом исключения.
Вот несколько примеров:
Каждая из этих инструкций действует как сигнал о том, что возникла какая-то проблема, которую необходимо обработать.
Поиск исключений
Создание исключений – это только одна часть процесса обработки исключений. Вернемся к нашей аналогии с американским футболом: что происходит после того, как судья выбросил штрафной флажок? Игроки замечают штраф и останавливают игру. Нарушается нормальный ход футбольного матча.
В C++ мы используем ключевое слово try для определения блока инструкций (называемого блоком try ). Блок try действует как наблюдатель, ищущий любые исключения, которые вызываются любой из инструкций в блоке try .
Вот пример блока try :
Обратите внимание, что блок try не определяет, КАК мы будем обрабатывать исключение. Он просто сообщает программе: «Эй, если какая-либо из инструкций внутри этого блока try вызовет исключение, захвати его!».
Обработка исключений
Наконец, конец нашей аналогии с американским футболом: после объявления штрафа и остановки игры судья определяет наказание и исполняет его. Другими словами, наказание должно быть выполнено до возобновления нормальной игры.
Фактически обработка исключений – это работа блока (ов) catch . Ключевое слово catch используется для определения блока кода (называемого блоком catch ), который обрабатывает исключения для одного типа данных.
Вот пример блока catch , который перехватывает исключения со значениями int :
Блоки try и блоки catch работают вместе – блок try обнаруживает любые исключения, которые вызываются инструкциями в блоке try , и направляет их для обработки в соответствующий блок catch . Блок try должен иметь сразу после себя, по крайней мере, один блок catch , но он также может иметь несколько блоков catch , идущих последовательно.
Как только исключение было перехвачено блоком try и направлено в блок catch для обработки, исключение считается обработанным, и выполнение возобновится в обычном режиме после блока catch .
Параметры catch работают так же, как параметры функции, причем параметр доступен в последующем блоке catch . Исключения базовых типов можно перехватывать по значению, но исключения небазовых типов следует перехватывать по константной ссылке, чтобы избежать ненужного копирования.
Как и в случае с функциями, если параметр не будет использоваться в блоке catch , имя переменной можно не указывать:
Это может помочь предотвратить предупреждения компилятора о неиспользуемых переменных.
throw , try и catch – собираем всё вместе
Вот полная программа, в которой используются инструкции throw , блок try и несколько блоков catch :
Выполнение показанного выше блока try / catch приведет к следующему результату:
Инструкция throw использовалась для вызова исключения со значением -1, которое имеет тип int . Затем эта инструкция throw была перехвачена включающим ее блоком try и направлена в соответствующий блок catch , который обрабатывает исключения типа int . Этот блок catch напечатал соответствующее сообщение об ошибке.
Как только исключение было обработано, программа продолжила работу в обычном режиме после блоков catch , напечатав " Continuing on our merry way ".
Обзор обработки исключений
Обработка исключений на самом деле довольно проста, и следующие два абзаца охватывают большую часть того, что вам нужно помнить о ней.
Когда выбрасывается исключение (с помощью throw ), выполнение программы сразу же переходит к ближайшему, включающему эту инструкцию throw , блоку try (при необходимости с распространением вверх по стеку, чтобы найти охватывающий блок try – мы обсудим это более подробно в следующем уроке). Если какой-либо из обработчиков catch , прикрепленных к этому блоку try , обрабатывает этот тип исключения, то этот обработчик выполняется, и исключение считается обработанным.
Если подходящих обработчиков catch нет, выполнение программы переходит к следующему охватывающему блоку try . Если до конца программы не удается найти подходящего обработчика catch , то программа завершится с ошибкой исключения.
Обратите внимание, что при сопоставлении исключений с блоками catch компилятор не будет выполнять неявные преобразования или расширяющие преобразования (продвижения)! Например, исключение char не будет соответствовать блоку catch int . Исключение типа int не соответствует блоку catch float . Однако приведение производного класса к одному из его родительских классов будет выполнено.
Вот и всё, что нужно помнить. Остальная часть этой главы будет посвящена демонстрации работы этих принципов.
Исключения обрабатываются немедленно
Вот небольшая программа, демонстрирующая, как исключения обрабатываются немедленно:
Эта программа проста настолько, насколько это возможно. Вот что происходит: инструкция throw , первая выполняемая инструкция, вызывает исключение типа double . Выполнение немедленно переходит к ближайшему охватывающему ее блоку try , который является единственным блоком try в этой программе. Затем на совпадение проверяются обработчики catch . Наше исключение относится к типу double , поэтому мы ищем обработчик catch типа double . У нас есть один такой, поэтому он и выполняется.
Следовательно, результат этой программы будет следующим:
Обратите внимание, что " This never prints " никогда не печатается, потому что исключение привело к немедленному переходу порядка выполнения к обработчику исключения для значений double .
Более реалистичный пример
Давайте посмотрим на пример, который не совсем академичен:
В этом коде пользователя просят ввести число. Если он вводит положительное число, оператор if не выполняется, исключение не генерируется и печатается квадратный корень из этого числа. Поскольку в этом случае исключение не возникает, код внутри блока catch никогда не выполняется. Результат будет примерно таким:
Если пользователь вводит отрицательное число, мы генерируем исключение типа const char* . Поскольку мы находимся в блоке try и соответствующий обработчик исключений найден, управление немедленно передается обработчику исключений const char* . Результат:
К настоящему моменту вы должны понять основную идею исключений. В следующем уроке мы приведем еще немало примеров, чтобы показать, насколько гибкими они являются.
Что обычно делают блоки catch
Если исключение направлено в блок catch , оно считается «обработанным», даже если этот блок catch пуст. Однако обычно вы захотите, чтобы блоки catch делали что-то полезное. Блоки catch выполняют три общих действия, когда перехватывают исключение:
Throw c что это
One of the advantages of C++ over C is Exception Handling. Exceptions are runtime anomalies or abnormal conditions that a program encounters during its execution. There are two types of exceptions: a)Synchronous, b)Asynchronous (i.e., exceptions which are beyond the program’s control, such as disc failure, keyboard interrupts etc.). C++ provides the following specialized keywords for this purpose:
try: Represents a block of code that can throw an exception.
catch: Represents a block of code that is executed when a particular exception is thrown.
throw: Used to throw an exception. Also used to list the exceptions that a function throws but doesn’t handle itself.
Why Exception Handling?
The following are the main advantages of exception handling over traditional error handling:
1) Separation of Error Handling code from Normal Code: In traditional error handling codes, there are always if-else conditions to handle errors. These conditions and the code to handle errors get mixed up with the normal flow. This makes the code less readable and maintainable. With try/catch blocks, the code for error handling becomes separate from the normal flow.
2) Functions/Methods can handle only the exceptions they choose: A function can throw many exceptions, but may choose to handle some of them. The other exceptions, which are thrown but not caught, can be handled by the caller. If the caller chooses not to catch them, then the exceptions are handled by the caller of the caller.
In C++, a function can specify the exceptions that it throws using the throw keyword. The caller of this function must handle the exception in some way (either by specifying it again or catching it).
3) Grouping of Error Types: In C++, both basic types and objects can be thrown as exceptions. We can create a hierarchy of exception objects, group exceptions in namespaces or classes and categorize them according to their types.
C++ Exceptions:
When executing C++ code, different errors can occur: coding errors made by the programmer, errors due to wrong input, or other unforeseeable things.
When an error occurs, C++ will normally stop and generate an error message. The technical term for this is: C++ will throw an exception (error).
C++ try and catch:
Exception handling in C++ consists of three keywords: try, throw and catch:
The try statement allows you to define a block of code to be tested for errors while it is being executed.
The throw keyword throws an exception when a problem is detected, which lets us create a custom error.
The catch statement allows you to define a block of code to be executed if an error occurs in the try block.
The try and catch keywords come in pairs:
We use the try block to test some code: If the value of a variable “age” is less than 18, we will throw an exception, and handle it in our catch block.
In the catch block, we catch the error if it occurs and do something about it. The catch statement takes a single parameter. So, if the value of age is 15 and that’s why we are throwing an exception of type int in the try block (age), we can pass “int myNum” as the parameter to the catch statement, where the variable “myNum” is used to output the value of age.
If no error occurs (e.g. if age is 20 instead of 15, meaning it will be greater than 18), the catch block is skipped.
Exception Handling in C++
1) The following is a simple example to show exception handling in C++. The output of the program explains the flow of execution of try/catch blocks.
Name already in use
docs / docs / csharp / language-reference / keywords / throw.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
throw (C# Reference)
Signals the occurrence of an exception during program execution.
The syntax of throw is:
where e is an instance of a class derived from xref:System.Exception?displayProperty=nameWithType. The following example uses the throw statement to throw an xref:System.IndexOutOfRangeException if the argument passed to a method named GetNumber does not correspond to a valid index of an internal array.
Method callers then use a try-catch or try-catch-finally block to handle the thrown exception. The following example handles the exception thrown by the GetNumber method.
Re-throwing an exception
throw can also be used in a catch block to re-throw an exception handled in a catch block. In this case, throw does not take an exception operand. It is most useful when a method passes on an argument from a caller to some other library method, and the library method throws an exception that must be passed on to the caller. For example, the following example re-throws an xref:System.NullReferenceException that is thrown when attempting to retrieve the first character of an uninitialized string.
[!IMPORTANT] You can also use the throw e syntax in a catch block to instantiate a new exception that you pass on to the caller. In this case, the stack trace of the original exception, which is available from the xref:System.Exception.StackTrace property, is not preserved.
The throw expression
throw can be used as an expression as well as a statement. This allows an exception to be thrown in contexts that were previously unsupported. These include:
the conditional operator. The following example uses a throw expression to throw an xref:System.ArgumentException if a method is passed an empty string array.
the null-coalescing operator. In the following example, a throw expression is used with a null-coalescing operator to throw an exception if the string assigned to a Name property is null .