// The Demo code below can be directly copied to the file and executed after compilation by the G ++ Compiler
# Include <stdlib. h>
# Include <time. h>
# Include <stdio. h>
# Include <unistd. h>
# Include <string>
# Include <iostream>
Using namespace STD;
// Define the exception class for testing
Class myexception
{
Public:
Myexception (string name = "NONE"): m_name (name)
{
Cout <"constructs a myexception exception object named:" <m_name <Endl;
}
Myexception (const myexception & old_e)
{
M_name = old_e.m_name;
Cout <"copy a myexception exception object named:" <m_name <Endl;
}
Myexception & operator = (const myexception & old_e)
{
M_name = old_e.m_name;
Cout <"assign a value to copy a myexception exception object named:" <m_name <Endl;
Return * this;
}
Virtual ~ Myexception ()
{
Cout <"destroy a myexception exception object named:" <m_name <Endl;
}
String getname ()
{
Return m_name;
}
Protected:
String m_name;
};
Void test_fun1 ()
{
Try
{
Cout <"1" <Endl;
// Construct an exception object, which is a local variable
Myexception ex_obj1 ("ex_obj1 ");
Cout <"2" <Endl;
/* An exception object is thrown here. Note that the compiler will copy a new exception object-Temporary Variable-this is equivalent to returning a copy to the exception stack, so it will call the copy
The constructor will analyze the local variables from try to throw before the jump (except the one in the exception stack will be retained until the corresponding Catch Block
Analyzes the structure only after the end )*/
Throw ex_obj1;
Cout <"3" <Endl; // not executed
}
/* This method will first copy a copy from the exception stack to the current parameter E. Therefore, a copy constructor is called. After processing, before the Catch Block ends
The exception object in the exception stack and E's destructor are called respectively. Therefore, two destructor calls are executed, similar to passing parameters in function calls. The difference is that the exception object
Real parameters are copied from the exception stack to the form parameter E */
Catch (myexception E)
{
Cout <E. getname () <Endl;
// The exception object of the exception stack will be destroyed by calling the corresponding destructor after the Catch Block.
}
Catch (...)
{
Cout <"catch unknow exception" <Endl ;}
}
Void test_fun2 ()
{
Try
{
Cout <"1" <Endl;
// Construct an exception object, which is a local variable
Myexception ex_obj1 ("ex_obj1 ");
Cout <"2" <Endl;
/* An exception object is thrown here. Note that the compiler will copy a new exception object and a temporary variable. At this time, it is equivalent to returning a copy to the exception stack. Therefore, the copy constructor is called.
In addition, the local variables from try to throw are all analyzed before conversion */
Throw ex_obj1;
}
/* This method directly uses the reference of the exception object in the exception stack. Therefore, a call to the copy constructor that copies the object to E and the Destructor after the Catch Block is missing */
Catch (myexception & E)
{
Cout <E. getname () <Endl;
}
}
// This method is the most recommended method, because it only needs to be constructed and parsed once, and there is no memory leakage at the same time
Void test_fun3 ()
{
Try
{
// In this way, an exception object is directly constructed and put on the exception stack, and then redirected. Therefore, no local temporary variables are created or destructed.
Throw myexception ("ex_obj1 ");
}
// This method directly uses the reference of the exception object in the exception stack. Therefore, a call to the copy constructor that copies the object to E and the Destructor after the Catch Block is missing.
Catch (myexception & E)
{
Cout <"& E" <Endl;
Cout <E. getname () <Endl;
}
Catch (myexception * E)
{
Cout <"* E" <Endl;
Cout <e-> getname () <Endl;
}
}
Void test_fun4 ()
{
Try
{
// In this way, an exception object is directly constructed and put on the exception stack, and then redirected. Therefore, no local temporary variables are created or destructed.
Throw myexception ("ex_obj1 ");
}
// This method will first copy a copy from the exception stack to the current parameter E. Therefore, a copy constructor is called. After processing, before the Catch Block ends
// Call the exception object in the exception stack and E's destructor respectively, so the two destructor calls are executed.
Catch (myexception E)
{
Cout <E. getname () <Endl;
}
}
// The pointer method is considered below
Void test_fun5 ()
{
Try
{
/* You can add static variables to the static storage area. In this case, the address can be passed and the object is considered an exception object, therefore, the corresponding destructor will be called to destroy the Catch Block */
Myexception ex_obj1 ("ex_obj1 ");
// Cout <& ex_obj1 <Endl;
// Myexception * E = & ex_obj1;
// Cout <e-> getname () <Endl;
/* This method is invalid. Although the address has been thrown out, the corresponding exception object will be destructed. Therefore, it is of little significance to obtain the address during cache.
This is equivalent to the same address of the return local variable in function call */
Throw & ex_obj1;
}
Catch (myexception * E)
{
// Cout <e <Endl;
Cout <e-> getname () <Endl;
}
}
Void test_fun6 ()
{
Try
{
// This throw method is not recommended. In this way, if the delete operation is not performed in catch, memory leakage will occur.
Myexception * PEX = new myexception ("ex_obj1 ");
Throw PEX;
}
Catch (myexception * E)
{
// Cout <e <Endl;
Cout <e-> getname () <Endl;
If (null! = E)
{
Delete E; // but it cannot be confirmed whether the corresponding address is built based on new. It may be static stack allocation. In this case, although the address is captured, no Delete is required.
}
}
}
Int main (INT iargc, char ** ppargv)
{
Test_fun1 ();
Test_fun2 ();
Test_fun3 ();
Test_fun4 ();
Test_fun5 ();
Test_fun6 ();
}