C ++ exception and exception
This article describes all exceptions related to C ++:
Never let exceptions escape the destructor
- There are two main reasons to prevent exceptions from escaping from destructor:
1. The terminate function is called to prevent stack expansion during exception handling. The program will end, and sometimes the error is not that serious.
[Insert: When will the terminate function be called?]
[Answer: By default, the terminate handler callabort. But this behavior can be redefined by calling set_terminate.
This function is automatically called when no catch handler can be found for a thrown exception, or for some other exceptional circumstance that makes impossible to continue the exception handling process.
// If no catch Block exists for an exception, the terminate function is automatically called or the exception cannot be handled.
This function is provided so that the terminate handler can be explicitly called by a program that needs to abnormally terminate, and works even if set_terminate has not been used to set a custom terminate handler (calling abort in this case ).
Terminate:
1. When an exception is sent and the constructor generates an exception
2. When an exception is sent or an destructor exception occurs
3. An exception is sent for the construction or analysis of a static object.
4. When an exception occurs for a function registered with atexit
5. When a custom exception is generated
6. When calling the default unexcepted () function (the unexcepted function throws unexpected exceptions)
2. It can help ensure that the destructor completes all the actions it should perform.
# Include <bits/stdc ++. h> using namespace std; class myexception {}; class Session {public: Session () {logCreation ();}~ Session () {try {// The try catch block here is a very important logDestruction ();} catch (...) {cout <"catch exception... "<endl ;}} private: static void logCreation () {cout <" enter... "<endl;} static void logDestruction () {cout <" out... "<endl; throw myexception () ;}; int main () {Session s; return 0 ;}
Catch sub-statement blocks VS. function calls are different in three categories: 1. exception objects are always copied. If you use the by value method, or even duplicate it twice. 2. The object thrown as an exception allows less conversion operations than "being passed to the function. 3. catch clauses match in the order they appear, that is, the "first fit" policy, unlike the "best fit" policy of function calls.
- Similarities: function parameters and exception transmission methods include by value, by reference, by pointer,
- Difference: When you call a function, the control will return to the calling end of the function after the call is complete. However, when you throw an exception, the control will never return to the throwing end.
- Difference: the binding method of the function. If it is to pass a value, it is to pass a copy of the object. If it is a reference, it is directly bound to the object. However, this is not true for exceptions. no matter whether the catch parameter of your exception is a value or a reference, all the objects that are passed to the catch Block are copies of the object. (Why? Because once the control right leaves the function, all the local objects of the function are out of the living space and will be automatically analyzed, the object passed to the catch block is an destructed object, which is obviously incorrect. This conclusion is true even if the lifetime of the temporary object is not limited to this function ). Here, the "exception object will always cause the row to be copied", which directly leads to slow exception Handling than function call !!!
- When object replication is treated as an exception, the replication behavior is executed by the object's copy constructor. This copy constructor corresponds to the static type of the object !! Not dynamic type !! For example, the following code:
Class Base {public: Base () {cout <"ctor in Base... "<endl;} Base (const Base &) {cout <" copy ctor in Base... "<endl ;}}; class Derived: public Base {public: Derived () {cout <" ctor in Derived... "<endl;} Derived (const Derived & B): Base (B) {cout <" copy ctor in Derived... "<endl ;}}; void f () {Derived d; // print: ctor in Base ctor in Derived Base & B = d; cout <" throw... "<endl; throw B; // copy ctor in Base} void test () {try {f (); cout <" never be here... "<endl;} catch (Base) // if it is Base, print: copy ctor in Base. If it is Base reference, so no output of anything {cout <"catch... "<endl ;}int main () {test (); return 0 ;}
- From the above, we know that "the exception object is a copy of other objects". Here we will see how to pass exception in different catch blocks !!!
The following throw and throw are used to simulate the operation to continue passing the current exception in the catch Block respectively.
// Use the throw statement to continue passing the current exception. If throw is used directly, the actual type of the exception originally passed is passed (throw in test1) // If throw + catch parameters are used, the static type is passed. Class Base {public: Base () {cout <"ctor in Base... "<endl;} Base (const Base &) {cout <" copy ctor in Base... "<endl ;}}; class Derived: public Base {public: Derived () {cout <" ctor in Derived... "<endl;} Derived (const Derived & B): Base (B) {cout <" copy ctor in Derived... "<endl ;}}; void f1 () {try {Derived d; // ctor in Base, ctor in Derived Base & B = d; cout <"throw... "<endl; // The value of throw Is the Derived object throw d; // copy ctor in Base, copy ctor in Derived, here we see the static type !!!} Catch (Base & w) // Base & can catch the preceding Derived exception. Both Base and Base & can catch the Derived exception. // If Derived is used, the preceding throw cannot be captured here if B is used as the throw. The method for binding parameters is the same as that for common function calls. {Cout <"throw current exception 1, using throw only... "<endl; throw; // If throw is used directly, even if the catch above binds a Derived object to a Base object, the original Derived object is passed here.} Void test1 () {try {f1 (); cout <"never be here... "<endl;} catch (Derived) // copy ctor in Base, copy ctor in Derived //} catch (Base) // copy ctor in Base. {cout <"catch... "<endl ;}} void f2 () {try {Derived d; // print: ctor in Base ctor in Derived Base & B = d; cout <"throw in f2... "<endl; throw B; // copy ctor in Base // The throw passed here is of the static type.} Catch (Base & w) {cout <"throw current exception 2" <endl; throw; // copy ctor in Base} void test2 () {try {f2 (); cout <"never be here in test2... "<endl;} catch (Base &) // if it is Base, print: copy ctor in Base. If it is Base reference, so no output anything {cout <"catch in test2... "<endl ;}int main () {cout <" 1; "<endl; test1 (); cout <" 2: "<endl; test2 (); return 0 ;}
- Difference: A thrown object (apparently a temporary object based on the above) can be captured in the by reference mode, and does not need to be captured in the by reference to const mode, however, it is not allowed to pass a temporary object to a non-const-reference parameter during function calling. However, exception is valid.
[Why is it not allowed to pass a temporary object to a non-const-reference parameter.]
Consider the following example:
Void f (const string & s) {cout <s <endl; cout <"const-reference... "<endl; return;} void f2 (string & s) {cout <" non-const reference... "<endl; return;} int main (void) {char buff [20] =" 1234 "; // The f and f2 functions need a string object, however, the buff character array is passed, so there is an implicit type conversion here to generate a temporary string object. F (buff); // call successful. Because it is a const, there is no need to change anything. F2 (buff); // call failed. Cause: f2 requires the string non-const reference, which means that the f2 function may modify the string s, at this time, the temporary object passed to // f2 is a string. When the function exits, the real parameter is not changed, and all operations are applied to the temporary parameter s, obviously, this is not the programmer's intention. We pass a // non-const reference to f2, and we want to modify the buff real parameter. Return 0 ;}
- Difference: If a function independent variable is passed by value, a copy is made to the passed object, which is stored in the corresponding function parameter; what if exception is passed in the by value method? For example:
Catch (Base B )... // You are expected to pay the construction cost of the "Two copies" of the "thrown". One is used for the "temporary object generated by any exception, another is "copying temporary objects to B ".
- If you use the by reference method, the function does not need any extra action, but the exception still has the cost of constructing a copy of the "thrown.
If an exception is passed by pointer, you must note that you must never run a pointer pointing to a local object. This is also a situation that must be taken into account for "Compulsory Copy operations.
Difference: the throw clause matches the catch parameter !!
The matching process between exception and catch clauses is only two conversions: 1. Class conversion in the inherited architecture. (A catch clause written for the Base class exception can capture an exception of the derived class.) Note: This conversion rule applies to the use of by value, by reference, or by pointer. 2. convert a "type Pointer" to a "type Pointer". For example, a catch clause designed for: const void * can capture exceptions of any type of pointer.
Difference: catch clauses always match in the order of appearance. That is to say, the catch clause for Derived class exception must be placed before the catch clause for Base class exception.
Catch exception By reference
Reason:
+ If it is by pointer, you need an object that will not be destroyed beyond this scope. At this time, global and static can help, but programmers may forget this; if an exception object is constructed temporarily during throw, for example, throw new exception, will the catch clause Delete this object? It is true that if it is global or static, you obviously do not need to delete it, but if it is new, you obviously need to delete it.
+ If it is by value, the object is cut. When a Derived exception object is given to a Base exception, the object is cut, if you call a virtual function in the catch Block, the version of the function is only the version of the base class. Obviously, this is not what we want.
Use Catch exception by reference to avoid these problems.
With the exception of what is it?
With the exception
Basic Translation
Except
Network Definition
With the exception of: Except... |
With the exception ...:
W> with the exception of <c:...
Encyclopedia
Exception
Exception [ik semi sep limit n] n. exception. Cap/cep/cip/ceive = to take, which is derived from the Latin capere, "take, seize ". Captor (n. catch, catch fast... details»
Search exception
Java Exception
Java has many exceptions, but the common exceptions are as follows:
Import java. nio .*;
Import java. util .*;
Class TestException {
Public static void main (String [] args ){
TestException t = new TestException ();
T. testIndexOutOfBoundsException ();
}
// 1. ArithmeticException exception. Triggered when the divisor is 0
Public void testArithmeticException (){
Int a = 10;
Int B = 0;
Int c = a/B;
}
// 2. ArrayStoreException exception. Triggered when the array type is incorrect.
Public void testArrayStoreException (){
Object x [] = new String [3];
X [0] = new Integer (0 );
}
// 3. BufferOverflowException exception.
Public void testBufferOverflowException (){
Int cap = 10;
ByteBuffer bf = ByteBuffer. allocate (cap );
System. out. println (bf );
For (int I = 0; I <cap; I ++ ){
Bf. put (byte) I );
}
System. out. println (bf );
// Cause exception
Bf. put (byte) 10 );
}
// 4. BufferUnderflowException exception.
Public void testBufferUnderflowException (){
Int cap = 10;
ByteBuffer bf = ByteBuffer. allocate (cap );
System. out. println (bf );
For (int I = 0; I <cap; I ++ ){
Bf. put (byte) I );
}
System. out. println (bf );
// Cause exception
Bf. get ();
}
// 5. ClassCastException exception. Triggered when the Cast type is incorrect.
Public void testClassCastException (){
Object x = new Integer (0 );
System. out. println (String) x );
}
// 6. EmptyStackException exception. Triggered when the stack is empty
Public void testEmptyStackException (){
Stack t = new Stack ();
T. push (new Object ());
T. pop ();
// Cause exception
T. pop ();
}
// 7. IllegalArgumentExcept ...... remaining full text>