0% found this document useful (0 votes)
10 views3 pages

C++ Exception Handling Tutorial

The document provides a comprehensive tutorial on handling exceptions in C++, explaining how to use try-catch blocks to manage runtime errors. It covers the syntax for throwing exceptions, chaining multiple handlers, and the use of standard exceptions from the C++ Standard library. Additionally, it discusses deprecated dynamic exception specifications and the importance of exception types in handling errors effectively.

Uploaded by

abdl rasyid
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views3 pages

C++ Exception Handling Tutorial

The document provides a comprehensive tutorial on handling exceptions in C++, explaining how to use try-catch blocks to manage runtime errors. It covers the syntax for throwing exceptions, chaining multiple handlers, and the use of standard exceptions from the C++ Standard library. Additionally, it discusses deprecated dynamic exception specifications and the importance of exception types in handling errors effectively.

Uploaded by

abdl rasyid
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

6/3/2021 Exceptions - C++ Tutorials

Search: Go
Not logged in

Tutorials C++ Language Exceptions register log in

C++
Information
Tutorials
Reference
Articles
Forum

Tutorials Exceptions
C++ Language Exceptions provide a way to react to exceptional circumstances (like runtime errors) in programs by transferring control
Ascii Codes to special functions called handlers.
Boolean Operations
Numerical Bases To catch exceptions, a portion of code is placed under exception inspection. This is done by enclosing that portion of
code in a try-block. When an exceptional circumstance arises within that block, an exception is thrown that transfers
C++ Language the control to the exception handler. If no exception is thrown, the code continues normally and all handlers are
Introduction: ignored.
Compilers
Basics of C++: An exception is thrown by using the throw keyword from inside the try block. Exception handlers are declared with the
Structure of a program keyword catch, which must be placed immediately after the try block:
Variables and types
Constants 1 // exceptions An exception occurred. Exception Nr. 20
Operators 2 #include <iostream>
Basic Input/Output
3 using namespace std;
4
Program structure:
5 int main () {
Statements and flow control 6 try
Functions 7 {
Overloads and templates 8 Edit
throw 20;
9 } &
Name visibility
10 catch (int e) Run
Compound data types:
11 {
Arrays
12 cout << "An exception occurred. Exception Nr. " << e << '\n';
Character sequences
13 }
Pointers 14 return 0;
Dynamic memory 15 }
Data structures
Other data types
Classes: The code under exception handling is enclosed in a try block. In this example this code simply throws an exception:
Classes (I)
Classes (II) throw 20;
Special members
Friendship and inheritance
Polymorphism
A throw expression accepts one parameter (in this case the integer value 20), which is passed as an argument to the
Other language features: exception handler.
Type conversions
Exceptions The exception handler is declared with the catch keyword immediately after the closing brace of the try block. The
Preprocessor directives syntax for catch is similar to a regular function with one parameter. The type of this parameter is very important, since
Standard library: the type of the argument passed by the throw expression is checked against it, and only in the case they match, the
Input/output with files exception is caught by that handler.

Multiple handlers (i.e., catch expressions) can be chained; each one with a different parameter type. Only the handler
whose argument type matches the type of the exception specified in the throw statement is executed.

If an ellipsis (...) is used as the parameter of catch, that handler will catch any exception no matter what the type of
the exception thrown. This can be used as a default handler that catches all exceptions not caught by other handlers:

1 try {
2 // code here
3 }
4 catch (int param) { cout << "int exception"; }
5 catch (char param) { cout << "char exception"; }
6 catch (...) { cout << "default exception"; }

In this case, the last handler would catch any exception thrown of a type that is neither int nor char.

After an exception has been handled the program, execution resumes after the try-catch block, not after the throw
statement!.

It is also possible to nest try-catch blocks within more external try blocks. In these cases, we have the possibility that
an internal catch block forwards the exception to its external level. This is done with the expression throw; with no
arguments. For example:

1 try {
2 try {
3 // code here
4 }
5 catch (int n) {
6 throw;
7 }
8 }
9 catch (...) {
10 cout << "Exception occurred";
11 }

Exception specification
Older code may contain dynamic exception specifications. They are now deprecated in C++, but still supported. A
dynamic exception specification follows the declaration of a function, appending a throw specifier to it. For example:

double myfunction (char param) throw (int);

[Link] 1/3
6/3/2021 Exceptions - C++ Tutorials

This declares a function called myfunction, which takes one argument of type char and returns a value of type double. If
this function throws an exception of some type other than int, the function calls std::unexpected instead of looking for
a handler or calling std::terminate.

If this throw specifier is left empty with no type, this means that std::unexpected is called for any exception. Functions
with no throw specifier (regular functions) never call std::unexpected, but follow the normal path of looking for their
exception handler.

1 int myfunction (int param) throw(); // all exceptions call unexpected


2 int myfunction (int param); // normal exception handling

Standard exceptions
The C++ Standard library provides a base class specifically designed to declare objects to be thrown as exceptions. It is
called std::exception and is defined in the <exception> header. This class has a virtual member function called what
that returns a null-terminated character sequence (of type char *) and that can be overwritten in derived classes to
contain some sort of description of the exception.

1 // using standard exceptions My exception happened.


2 #include <iostream>
3 #include <exception>
4 using namespace std;
5
6 class myexception: public exception
7 {
8 virtual const char* what() const throw()
9 {
10 return "My exception happened";
11 }
12 } myex; Edit
13 &
14 int main () { Run
15 try
16 {
17 throw myex;
18 }
19 catch (exception& e)
20 {
21 cout << [Link]() << '\n';
22 }
23 return 0;
24 }

We have placed a handler that catches exception objects by reference (notice the ampersand & after the type),
therefore this catches also classes derived from exception, like our myex object of type myexception.

All exceptions thrown by components of the C++ Standard library throw exceptions derived from this exception class.
These are:

exception description
bad_alloc thrown by new on allocation failure
bad_cast thrown by dynamic_cast when it fails in a dynamic cast
bad_exception thrown by certain dynamic exception specifiers
bad_typeid thrown by typeid
bad_function_call thrown by empty function objects
bad_weak_ptr thrown by shared_ptr when passed a bad weak_ptr

Also deriving from exception, header <exception> defines two generic exception types that can be inherited by custom
exceptions to report errors:

exception description
logic_error error related to the internal logic of the program
runtime_error error detected during runtime

A typical example where standard exceptions need to be checked for is on memory allocation:

1 // bad_alloc standard exception


2 #include <iostream>
3 #include <exception>
4 using namespace std;
5
6 int main () {
7 try
8 { Edit
9 int* myarray= new int[1000]; &
10 } Run
11 catch (exception& e)
12 {
13 cout << "Standard exception: " << [Link]() << endl;
14 }
15 return 0;
16 }

The exception that may be caught by the exception handler in this example is a bad_alloc. Because bad_alloc is
derived from the standard base class exception, it can be caught (capturing by reference, captures all related classes).

Previous: Next:
Type conversions Preprocessor directives
Index

[Link] 2/3
6/3/2021 Exceptions - C++ Tutorials

Home page | Privacy policy


© [Link], 2000-2021 - All rights reserved - v3.2
Spotted an error? contact us

[Link] 3/3

Common questions

Powered by AI

C++ handles runtime errors through exceptions by transferring control to special functions called handlers. This process begins by enclosing a block of code within a try block. If an exceptional circumstance arises during execution of this code, an exception is thrown using the throw keyword. This transfers control to an exception handler declared with the catch keyword, placed immediately after the try block. The handler's parameter type must match the type of the thrown expression to be executed. Multiple handlers can be used to catch different types of exceptions, and a catch-all handler can be used with catch(...). After handling, execution resumes after the try-catch block .

Exception handling in C++ offers several benefits over traditional error handling methods like return codes or error flags. It provides a clear and explicit mechanism to separate error-handling code from the main logic, improving readability and maintainability by allowing functions to handle errors from a distance. Furthermore, it supports complex error propagation paths through nested try-catch blocks. However, drawbacks include potentially nontrivial performance costs due to stack unwinding, the complexity of ensuring correct state restoration, and the difficulty in understanding code with many exceptions and handlers, especially for large, multi-threaded applications .

Nested try-catch blocks in C++ allow for structured exception handling across different scopes of program logic. It involves placing a try-catch block inside another try block. If an inner catch cannot handle the exception, it can be re-thrown using 'throw;', passing the exception to an enclosing catch block. This enables handling exceptions at several levels of program logic, catering to cases where local handling might be insufficient and deferring responsibility to higher levels .

When dealing with polymorphic exceptions in C++, the throw expression's type must match the parameter type specified in the catch block for the exception to be caught. If the exception is thrown through a base class pointer, and if the catch block handles exceptions by reference, it is capable of catching exceptions derived from a base class like 'std::exception'. This allows flexibility in handling derived exceptions, provided the catch block parameter uses reference or base class pointers .

In legacy C++ exception handling, 'std::unexpected' was invoked when a function, defined with dynamic exception specifications, threw an exception type not listed in its throw specifier. Instead of attempting to handle the exception or calling std::terminate, std::unexpected was called as part of the exception handling process. This provided a mechanism to handle unforeseen exceptions, although it lacked the flexibility and efficiency of modern alternatives, hence leading to its deprecation .

The <exception> header defines two generic exception types in C++: 'logic_error' and 'runtime_error'. 'logic_error' is intended for errors related to the internal logic of the program, implying issues that could be avoided by changing the program code. 'runtime_error', on the other hand, is used for errors detected during runtime, often due to factors beyond the control of the program's internal logic, such as hardware failures. Both classes serve as bases for creating more specific custom exceptions, providing a structured means to handle different error categories .

The 'std::exception' class in C++ is a base class for all standard library exceptions, designed to be thrown as exception objects. It is defined in the <exception> header and features a virtual member function, 'what', which returns a description of the exception as a null-terminated character sequence. Derived classes can override 'what' to provide specific exception messages. All standard library exceptions derive from this base class, allowing uniform handling of a wide array of error types through polymorphic catch blocks .

Dynamic exception specifications in C++ were plagued by several drawbacks, including added runtime overhead due to exception checking, and implementation complexities such as interacting with 'std::unexpected'. As they only specified exceptions a function might throw, they did not enforce any compile-time guarantees, weakening type safety. Modern C++ addresses these issues with the introduction of the noexcept specifier, which provides compile-time checking and potential optimizations for performance by signaling that a function does not throw exceptions, enhancing simplicity, and safety .

Dynamic exception specifications are deprecated in C++, meaning they are old-style and not recommended for use in new code. They append a throw specifier to a function declaration, indicating which exceptions the function might throw. If other exceptions are thrown, std::unexpected is called instead of searching for a handler or calling std::terminate. Modern C++ emphasizes noexcept specifiers instead, which provide a more efficient way to handle exceptions without specifying types .

The 'throw' keyword in C++ is used to signal an exception has occurred within a try block. It transfers control to an associated catch block. A throw expression includes a parameter that is passed as an argument to the exception handler, which must have a matching parameter type to catch the thrown exception .

You might also like