|
|
(43 intermediate revisions by 11 users not shown) |
Line 1: |
Line 1: |
− | {{title|try-catch statement}}
| |
− | {{cpp/language/navbar}}
| |
− | Used to attempt the execution of a compound-statement, while catching and handling exceptions that may have been thrown as a result of this attempt.
| |
| | | |
− | ===Syntax===
| |
− |
| |
− | {{sdsc begin}}
| |
− | {{sdsc | num=1 | {{ttb|try { }} {{spar|statements}} {{ttb| } catch ( }} {{spar|exception-decl}} {{ttb| ) { }} {{spar|statements}} {{ttb| } }} }}
| |
− | {{sdsc | num=2 | {{ttb|try { }} {{spar|statements}} {{ttb| } catch ( }} {{spar|exception-decl-1}} {{ttb| ) { }} {{spar|statements}} {{ttb| } catch ( }} {{spar|exception-decl-2}} {{ttb| ) { }} {{spar|statements}} {{ttb| } }} }}
| |
− | {{sdsc | num=3 | {{ttb|try { }} {{spar|statements}} {{ttb| } catch ( }} {{spar|exception-decl}} {{ttb| ) { }} {{spar|statements}} {{ttb| throw; } }} }}
| |
− | {{sdsc | num=4 | {{ttb|try { }} {{spar|statements}} {{ttb| } catch ( ... ) { }} {{spar|statements}} {{ttb| } }} }}
| |
− | {{sdsc | num=5 | {{ttb|try : }} {{spar|ctor-init-list}} {{ttb| { }} {{spar|statements}} {{ttb| } catch ( }} {{spar|exception-decl}} {{ttb| ) { }} {{spar|statements}} {{ttb| } }} }}
| |
− | {{sdsc end}}
| |
− |
| |
− | ===Explanation===
| |
− |
| |
− | :{{small|See {{rlp|throw | throw exceptions}} for more information about throw exceptions}}
| |
− |
| |
− | The basic syntax (1) shows the basic components of a try-catch block. First, the keyword {{tt|try}} initiates a try-block in which {{spar|statements}} can be executed. Note that the try-block, from the opening curly-brace to its closing, follows the same scoping rules as any other scope (e.g. variables declared within the try-block are not available outside of it, including from the catch-block that follows). Then, the {{tt|catch}} statement acts as a specifier of the type of exception to be caught if thrown from within the try-block. The {{spar|exception-decl}} has the same syntax as the parameter declaration within a single-parameter function declaration (except that the type cannot be {{c|void}}, an incomplete type, or an rvalue-reference {{mark since c++11}}). Finally, the compound-statement {{tt| { }} {{spar|statements}} {{tt| } }} which follow the catch-statement is called the ''exception-handler'' and contains statements to be executed in response to the exception that was caught. Typical exception-handling code includes logging the error, employing an alternative method to what was attempted in the try-block, or re-packaging the exception into another thrown exception with additional information.
| |
− |
| |
− | In syntax (2), the illustration here is that a try-catch block is not limited to a single catch-block. Since different types of exceptions can be thrown from within the try-block, one can specify as many catch-blocks as necessary to handle all exceptions one wishes to handle. Note, however, that the order of appearance of the catch-statements is important, a thrown exception will be handled by the first catch-block, by order of appearance, whose {{spar|exception-decl}} is a valid match (and implicit conversions apply as well). In other words, it is ''not'' the ''best'' match that is chosen (as in function overloading rules), but the ''first'' match. If the thrown exception matches none of the catch-statements, then the exception is carried back until another enclosing try-block is reached or until the program is terminated due to an unhandled exception.
| |
− |
| |
− | In syntax (3), the only addition is the {{tt|throw;}} statement within the catch-block. The statement has the effect of re-throwing the same exception object which was caught by the catch-block. This is the only context in which an empty throw-statement is valid, and it's specific meaning is to re-throw the exception that was caught, and declared as {{spar|exception-decl}}.
| |
− |
| |
− | Syntax (4) is a so-called ''catch-all block''. The ''ellipsis operator'' {{tt|...}} (literally, three dots) can be used in-place of the {{spar|exception-decl}} to specify that any and all types of exceptions thrown in the try-block should be caught by the catch-block. This type of catch-all block is not useful for getting any information on the type of exception that was thrown, and since most exception objects are of classes derived from {{rlp|../error/exception/exception | std::exception}}, it is generally more useful to catch the exception as {{c|catch( std::exception& e )}}. However, the main purpose of a catch-all block is to ensure that no uncaught exceptions are leaked from a function, which is especially useful for special functions from which leaking exceptions can be dangerous, most notably, a destructor or a dynamically-linked external function.
| |
− |
| |
− | Syntax (5) is called a ''function-try-block'' and can be used to enclose an entire function body inside a try-block (with catch-blocks following it). This is especially useful to catch exceptions which could be thrown during the execution of a constructor's initialization list (construction of sub-objects of a class), in fact, it is the only way to do so. This ''function-try-block'' syntax is seldom used in any other context because it has no advantage as compared to a traditional try-catch block, and the resulting syntax is generally unappealing (and unfamiliar to most).
| |
− |
| |
− | ===Keywords===
| |
− |
| |
− | {{ltt|cpp/keyword/try}},
| |
− | {{ltt|cpp/keyword/catch}},
| |
− | {{ltt|cpp/keyword/throw}}
| |
− |
| |
− | ===Example===
| |
− | {{example
| |
− | | The following example demonstrates several usage cases of the {{tt|try-catch}} block
| |
− | | code=
| |
− | #include <iostream>
| |
− | #include <vector>
| |
− |
| |
− | int main()
| |
− | {
| |
− | try {
| |
− | std::cout << "Throwing an integer exception...\n";
| |
− | throw int(42);
| |
− | } catch( int i ) {
| |
− | std::cout << " the integer exception was caught, with value: " << i << '\n';
| |
− | }
| |
− |
| |
− | try {
| |
− | std::cout << "Creating a vector of size 5... \n";
| |
− | std::vector<int> v(5);
| |
− | std::cout << "Accessing the 11th element of the vector...\n";
| |
− | v.at(10); // the at() function will check the range.
| |
− | } catch( std::exception& e) {
| |
− | std::cout << " a standard exception was caught, with message '" << e.what() << "'\n";
| |
− | }
| |
− |
| |
− | }
| |
− | | output=
| |
− | Throwing an integer exception...
| |
− | the integer exception was caught, with value: 42
| |
− | Creating a vector of size 5...
| |
− | Accessing the 11th element of the vector...
| |
− | a standard exception was caught, with message 'out_of_range'
| |
− | }}
| |
− |
| |
− | [[de:cpp/language/try catch]]
| |
− | [[es:cpp/language/try catch]]
| |
− | [[fr:cpp/language/try catch]]
| |
− | [[it:cpp/language/try catch]]
| |
− | [[ja:cpp/language/try catch]]
| |
− | [[pt:cpp/language/try catch]]
| |
− | [[ru:cpp/language/try catch]]
| |
− | [[zh:cpp/language/try catch]]
| |