In a program with exceptions, the exit of the function becomes elusive, which everyone knows. However, in many cases, we want the function to do something before exiting. in Java, we use try... finally, we will do this. In C ++, We have RAII. However, sometimes RAII looks clumsy. If we want a function to output a warning to the console no matter how it exits, do we need to write a class for it? This not only makes it difficult to understand the code dispersion, but also "contaminated" The namespace.
Fortunately, we have a local class, which seems useless, but is suitable for use here. For the following code, if RAII is not used, it is almost impossible to complete the "execute every exit" action:
# Include <iostream>
# Include <exception>
Int func (int I)
{
Try
{
Switch (I)
{
Case 1:
Throw "I = 1 ";
Case 2:
Throw std: exception ("I = 2 ");
Case 3:
Throw 3;
Default:
Throw std: runtime_error ("default ");
}
Int ret = 1/I;
Return ret;
}
Catch (std: runtime_error & e)
{
Std: cout <"runtime_error:" <e. what () <std: endl;
}
Return 0;
}
Int main ()
{
For (INT I = 0; I <5; ++ I)
Try
{
STD: cout <"func (" <I <"):" <func (I) <STD: Endl;
}
Catch (...)
{
STD: cout <"func (" <I <") throws exception." <STD: Endl;
}
}
Output:
Runtime_error: Default
Func (0): 0
Func (1) throws exception.
Func (2) throws exception.
Func (3) throws exception.
Runtime_error: Default
Func (4): 0
It is not necessary to use conventional raiI. This is where the local class shows its skills:
# Include <iostream>
# Include <exception>
Int func (int I)
{
Struct finally
{
~ Finally () {std: cout <"func () is exiting" <std: endl ;}
} Finalizer;
Try
{
Switch (I)
{
Case 1:
Throw "I = 1 ";
Case 2:
Throw std: exception ("I = 2 ");
Case 3:
Throw 3;
Default:
Throw std: runtime_error ("default ");
}
Int ret = 1/I;
Return ret;
}
Catch (std: runtime_error & e)
{
Std: cout <"runtime_error:" <e. what () <std: endl;
}
Return 0;
}
Int main ()
{
For (int I = 0; I <5; ++ I)
Try
{
Std: cout <"func (" <I <"):" <func (I) <std: endl;
}
Catch (...)
{
Std: cout <"func (" <I <") throws exception." <std: endl;
}
}
Output:
Runtime_error: default
Func () is exiting
Func (0): 0
Func () is exiting
Func (1) throws exception.
Func () is exiting
Func (2) throws exception.
Func () is exiting
Func (3) throws exception.
Runtime_error: default
Func () is exiting
Func (4): 0
This is actually a disguised raiI, but it has some advantages over conventional implementation:
1. Code set for easy understanding
2. namespace will not be contaminated
3. All finalizers can be named in a uniform manner.
...
There should be something else, not to mention.