Exception security "Go" in C + +

Source: Internet
Author: User
Tags mutex

It's very well written in the original, from here.

If a function is "exceptionally safe", the following two conditions must be met: 1. No resources are disclosed; 2. Data destruction is not allowed. Let's start with an example of two tails.

The first is an example of a resource leak. A class type that contains a mutex member mutex mutex, and a member function void Func (). Suppose the implementation of the Func function is as follows:

void Type::func ()  {      Lock (&mutex);      DoSomething ();      UnLock (&Mutex);  }  

The first is to obtain the mutex, the middle is to do the thing, and finally release the mutex. It's completely functional, no problem. But from an exceptional security standpoint, it does not meet the conditions. Because once the dosomething () function causes an exception, UnLock (&mutex) will not be executed, and the mutex will never be freed. In other words, it creates a resource leak.

Let's look at the second example of a data breach. This example is a member function of the overloaded ' = ' operator that we are familiar with. Still assume a class type, where one member is a pointer to a piece of resources (assuming type T). At this point we typically need to customize the copy constructor and the overloaded copy operators and destructors. (In most cases, these three members are always either present or not defined, because the compiler defines the so-called "rule of 3" rule in C + + by default.) No details are provided here). Here we only consider the problem of overloading the copy operator, and some of its code assumes the following:

classtype{ Public:    .... Type&operator= (ConstType &t) {if( This= = &t)return* This; Else{Delete m_t; m_t=NewT (t->m_t); return* This; }    }    ....    Private: T*m_t;};

The first is to determine if it is self-replicating, and if so, return directly to yourself. If not, safely frees the resource that is currently pointing, creates a resource that is exactly the same as the object resource being copied, points to it, and finally returns the copied object. Again, it's no problem to put aside the unusual security. However, given the exception security, once the "new T (t->m_t)" Throws an exception, m_t will point to a resource that has been deleted and does not really point to the same resource as the object being copied. In other words, the data of the original object is compromised.

The exception security function in C + + provides three levels of security:

1. Basic commitment: If an exception is thrown, any member within the object remains valid, without data corruption and resource leaks. But the actual state of the object is not estimated, that is not necessarily the state before the call, but at least to ensure that the object is in line with normal requirements.

2. Strongly guarantee that if an exception is thrown, the state of the object remains unchanged. That is, if the call succeeds, it is completely successful, and if the call fails, the object remains the state before the call.

3. Non-throwing Exception guarantee: The function promises not to throw any exceptions. All operations of the general built-in type are guaranteed to be non-throwing exceptions.

If a function does not provide one of the above guarantees, it does not have exception security.

Now let's solve the above two problems.

For resource leaks, the workaround is easy, which is to use objects to manage resources. RAII technology has been introduced before, here will not repeat. Instead of manipulating the mutex mutex directly in the function, we use an object that manages the mutex Mutexlock ml. The new implementation of the function is as follows:

void Type::func ()  {      Mutexlock ml (&mutex);      DoSomething ();  }  

After object ml is initialized, the mutex is automatically locked and then done. Finally, we are not responsible for releasing the mutex because the ML destructor is automatically freed for us. In this way, the instant dosomething () throws an exception, ML is always to be deconstructed, there is no need to worry about the mutex is not normal release of the problem.

For the second question, a classic strategy is called "Copy and Swap." The principle is simple: make a copy of the original object and make the necessary modifications on the copy. If any exception occurs, the original object is guaranteed to remain unchanged. If the modification succeeds, the copy is exchanged (swap) with the original object by a swap function that does not throw any exceptions. The new implementation of the function is as follows:

type& type::operator = (const type &t)  {      type tmp (t);      Swap (M_t,tmp-m_t);             return *this;  }  

Create a copy of the copied object T, TMP, at which point the original object has not been modified so that the original object is not affected even if an exception is thrown when the resource is requested. If the creation succeeds, the swap function of the temporary object is exchanged for the resource and the original object resource, and the swap function of the standard library promises not to throw an exception, so that the original object will successfully become the copy version of the object T. For this function, we can think of it as "strongly guaranteed" to be exceptionally safe.

Of course, it is not always possible to provide a strong guarantee. The level of exception security that a function can provide depends on its implementation. Consider the following example:

void Func ()  {      f1 ();      F2 ();  }  

If both F1 and F2 provide a "strong guarantee", then apparently the Func function is a security level with a "strong guarantee". However, if one of the F1 or F2 is not available, the Func function will no longer have a "strong guaranteed" rating, but depends on the lowest security level in F1 and F2.

Summarize:

In order for the code to have better exception security, the first is to "use objects to manage resources" to avoid resource leaks. Second, the level of exception security should be limited to a higher level as much as possible. "Strong assurance" can often be achieved through the COPY-AND-SWAP approach. But we should also know that "strong assurance" is not achievable for all situations, depending on the function you use in the implementation. The highest level of exception security provided by a function can only be the one that has the lowest exception security level in each function called in your implementation.

Reference: "Effective C + +", Third edition.

Exception security "Go" in C + +

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.