I. program error
Compilation error, that is, syntax error. The program cannot be generated to run the code.
Runtime error
Unpredictable logical errors
Predictable running exceptions
For example:
Dynamic space allocation may fail.
Opening the file may fail.
The denominator of Division operations may be 0.
Integer multiplication may overflow
Array out of bounds ......
Ii. Exceptions
(1) exception syntax
Throw expression;
Try
{
// Try statement Block
}
Catch (type 1 parameter 1)
{
// Exception Handling for type 1
}
Catch (Type 2 parameter 2)
{
// Exception Handling for type 2
}
...
Catch (Type N parameter n)
{
// Exception Handling for Type N
}
(2) thrown exceptions
You can throw a built-in type exception or a custom type exception.
Throw a Class Object and calls the copy constructor.
The local object created before an exception occurs is destroyed. This process is called Stack expansion.
(3) exception capture
An exception processor typically captures only one type of exception.
The parameter type of the exception processor is the same as that of the thrown exception.
... Can capture any exceptions
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
|
# Include <iostream> # Include <string> Using namespace STD;Class myexception { Public: Myexception (const char * message) : Message _ (Message) { Cout <"myexception..." <Endl; } Myexception (const myexception & other): Message _ (other. Message _) { Cout <"Copy myexception..." <Endl; } ~ Myexception () { Cout <"~ Myexception "<Endl; } Const char * What () const { Return message _. c_str (); } PRIVATE: String message _; }; Double divide (double A, double B) { If (B = 0.0) { Myexception E ("Division by zero "); Throw E; /* Throw myexception ("Division by zero ");*/ // Throw 1; } Else Return A/B; } Int main (void) { Try { Cout <divide (5.0, 0.0) <Endl; } Catch (myexception & E) { Cout <E. What () <Endl; } // Catch (INT) //{ // Cout <"int exception..." <Endl; //} Catch (double) { Cout <"double exception..." <Endl; } Catch (...) { Cout <"catch a exception..." <Endl; } } |
The program customizes an exception type myexception. From the output, we can see that the divide function first constructs a myexception Object E and calls the constructor, because E is a local object and needs to be parsed, call the copy constructor to construct another object before the analysis. The object will be referenced by the catch object, and the object will be destructed at the end of the catch object.
If a local object is not constructed and throw is used directly, for example, throw myexception ("Division by zero"), the copy constructor is not called and only one object exists, it is destructed at the end of the catch.
Assume that throw 1; and no catch (INT) can be caught even if catch (double) exists. type conversion is not performed, and catch (...) captured ,... can capture any exceptions.
(4) abnormal Propagation
1. Try blocks can be nested
2. The program looks for a matched exception processor in sequence. The thrown exception will be caught by the first type of exception processor.
If no exception processor is found after the try block in the inner layer, the exception is propagated to the Catch Block after the try block in the outer layer.
3. If no caught exception occurs, the terminate function is called. The terminate function calls the abort function by default to terminate the execution of the program.
You can use the set_terminate function to specify the function called before calling abort.
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
Void myterminate () { Cout <"myterminate..." <Endl; }Int main (void) { Set_terminate (myterminate ); Try { Try { Throw myexception ("test exception "); } Catch (INT) { Cout <"inner..." <Endl; Cout <"catch a int exception" <Endl; } // Catch (myexception & E) //{ // Cout <"inner..." <Endl; // Cout <E. What () <Endl; // Throw E; //} } Catch (INT) { Cout <"outer..." <Endl; Cout <"catch a int exception" <Endl; } Catch (myexception & E) { Cout <"outer..." <Endl; Cout <E. What () <Endl; } } |
Among them, the myexception class is as above, and the internal catch (myexception & E) is blocked in the program, so it is caught by the outer catch (myexception & E). If both of them are commented out, because no catch is found, the terminate function will be called.
The function sets the function myterminate called before the abort call. Therefore, output myterminate... and the program is terminated.
3. Stack Expansion
Search up the nested call link until a catch clause is found for the exception. This process is called Stack expansion.
Call the Destructor for a local object
Destructor should never throw an exception
The Destructor will be executed during the stack expansion. during the execution of the destructor, the exceptions that have been thrown but have not been processed. If the Destructor throws a new exception during this process, the terminate function of the standard library will be called.
Exception and constructor
An exception can be thrown in the constructor. If an exception is thrown in the constructor, the object may be partially constructed. Even if the object is only partially constructed, ensure that the constructed members are destroyed. (If the member is the pointer P, the normal delete p will not be executed because the Destructor will not be called; it is likely to cause memory leakage)
Refer:
C ++ primer version 4
Valid tive C ++ 3rd
C ++ programming specifications