Unusual security
Next twice, I will discuss "unusual security", and the C standard uses (in auto_ptr) but does not define the term. Within C , different authors use this term to express different meaning. In my topic, I define "unusual security" from two aspects:
l If an entity captures or throws an exception, it still maintains the semantics of its public assurance, it is "interface security". Depending on its guaranteed efforts, entities may not allow any exceptions to their users.
l If an exception does not lead to resource leakage or an undefined behavior, the entity is "behavior security". "Behavior Security" is generally forced. Fortunately, if "behavior security" is done, "Interface Security" is usually provided.
An unusual security is a bit icon. Const: Good design must consider it at the beginning, it can't remedy afterwards. But we started using an exception, so there is no "unusual security problem set" to guide us. In fact, I hope that through a hard way to master unusual security: bypass them at encoding by experience; or turn off abnormal characteristics, they think they are "too difficult" is correct.
I don't want to ly: Analytical design in design is too difficult. However, hard work also has a rich return. However, this theme is too difficult, and if you want to face it, you will spend a few months. My smallest goal is to show how to make them secure by lacking an unusual security, and motivating you to see and learn more things outside this topic.
1.1 constructor
If a regular member function
X.f ()
Throw an exception, you can tolerate this exception and try to call it again:
X x;
Bool done;
DO
{
Try
{
DONE = true;
x.f ();
}
Catch (...)
{
// Do Something to Recover, Then Retry
DONE = false;
}
}
While (! ";
However, if you try to call a constructor again, you actually call a completely different object:
Bool Done (false);
While (! done)
{
Try
{
DONE = true;
X; // Calls x :: x ()
}
// from this point forward, `x` Does not exist
Catch (...)
{
// Do Something to Recover, Then Retry
DONE = false;
}
}
You can't save an object that throws a texture; an abnormal existence indicates that object is dead.
When a constructor throws anomalies, it kills its host object without calling the destructor. Such a throwing behavior has hazards "behavior security": If this throwing constructor is allocated, you cannot rely on the analysis function to release them. General constructors and sectations are paired and look forward to the latter cleaning the former. This expectation is not satisfied if the designer is not called.
Finally, if you throw an exception from the constructor, and your class is a base class or sub-object of the user class, then the user class constructor must handle the exception thrown. Or it throws an exception to another user class constructor, so that it is pushed until the program is called Terminate (). In fact, the user must do the work you have not done (maintain the security of the constructor).
1.2 Problems about 取 取
The constructor throws an impulfors and reduces interface security and behavior. Do not let the constructor throw away unless there is no forced reason.
There are also different opinions that: an exception should be captured by the special code of this. Those who only receive exceptions quietly without processing their exceptions in violation of these anomalies. If a function is not ready to handle an exception correctly, it should pass this exception. The lowest fact is that some people must have an exception; if everyone put it, the program will terminate. You must also capture the conditions of triggering anomalies; if no one marks it, the program may terminate in any way, and I am afraid nothing.
An exception object warning us there is an error condition that should not be ignored. Unfortunately, this object may result in a new different error condition. When designing unusual security, you must take the principle between two sometimes conflict.
1. Info when the error occurs
2. Prevent this notification behavior causes other errors.
Because the constructive function throws an inexpensive side effect, you must be careful to weigh these two principles. I don't allow the constructor to write to the texture, which is designed to be in principle 2; but I don't want to recommend it as a universal principle, in other cases these two principles are equal. It's good to judge yourself.
1.3 destructor
The destructor has a weird reaction that can throw the procedure. It may thoroughly kill programs. According to C standards (Subclause 15.1.1, "The Terminate () function"), is briefly described below:
In some cases, exception handling must be abandoned to reduce some subtle mistakes. These circumstances include: as the destructuring function of the object to be destructed is treated during the decont fracture process. In these cases, the function void Terminate () is called. The returns will not be completed.
In short, the destructor should not prompt whether there is an abnormality. However, as I last mentioned, the new C standard runtime program uncaught_exception () can make the destructive function determine the abnormal environment they are. Unfortunately, I said last again, Visual C failed to properly support this function.
The problem is worse than I prompt. I wrote last time, Microsoft's uncaught_exception () function version must return false, so Visaul C always tells you that the destructive function does not have an abnormality in which it is never possible. If you transfer to Visual C from a environment that supports Uncaught_Exception, the previously working code may start to call Terminate ().
To try it, try the example:
#include
#include
#include
Using namespace std;
Static void my_terminate_handler (void)
{
Printf ("Library Lied; I'm in The Terminate Handler./N");
Abort ();
}
Class X
{
PUBLIC:
~ X ()
{
IF (uncaunht_exception ())
Printf ("Library Says Not To Throw./N");
Else
{
Printf ("Library Says I'm Ok to Throw./N");
Throw 0;
}
}
}
int main ()
{
Set_terminate (my_terminate_handler);
Try
{
X x;
Throw 0;
}
Catch (...)
{
}
Printf ("exiting normally./n");
Return 0;
}
With the C standard compatible environment, you get:
Library says not to throw.
EXITING NORMALLY.
But Visual C , you get:
Library Says I'm Ok to Throw.
Library Lied; I'm in The Terminate Handler.
And follow one program to terminate.
And with sleet you get Egg Roll.
Recommendation: Unless you know how you use the platform you use now, you should correctly support uncaught_exception (), don't call it.
1.4 partial deletion
Even if you know that you are not working abnormal, you should not throw it in the destructor. Consider the following example:
Class X
{
PUBLIC:
~ X ()
{
Throw 0;
}
}
int main ()
{
X * x = new x;
Delete X;
Return 0;
}
When Main () is executed to Delete X, the following two steps will occur in turn:
The destructor of X is called.
Operator delete is called to release X's memory space.
But because the destructive function of X throws an exception, Operator delete is not called. This hazards behavior. If you still don't believe, try this more complete example:
#include
#include
Class X
{
PUBLIC:
~ X ()
{
Printf ("DESTRUCTOR / N");
Throw 0;
}
Void * Operator new (size_t n) throw ()
{
Printf ("new / n");
Return Malloc (n);
}
Void Operator Delete (Void * P) throw ()
{
Printf ("delete / n");
IF (p! = null)
Free (p);
}
}
int main ()
{
X * x = new x;
Try
{
Delete X;
}
Catch (...)
{
Printf ("catch / n");
}
Return 0;
}
If the destructor does not leave the usual, the program output:
New
Destructor
Delete
In fact, the program output:
New
Destructor
Catch
Operator delete does not enter, the memory space of X is not released, the program has resource leaks, the press hammers your product for eating memory, and you go back to flipping burgers for a living.
Principle: Abnormal safety requirements You cannot throw theremons in the destructor. And there are different opinions on the structure of the structure, this is absolute. In order to clearly indicate intentions, it should be added to the abnormal complications in the application of throw ().
1.5 notice
I am ready to overwrite the template security, but I have no place. I will leave a next introduction and open the recommended reading table.