Reading notes effective C + + Item 14 copy behavior of the resource management class be cautious

Source: Internet
Author: User

1. Implement a resource management class yourself

Item 13 describes the concept of "when resource acquisition is also initialized (RAII)", a concept that is used as the "spine" of the resource management class, and also describes how auto_ptr and tr1::shared_ptr use heap resources to represent the concept. However, not all resources are created on the heap, and smart pointers such as auto_ptr and tr1::shared_ptr are not intended to be used as resource handles (handle) for such resources. You will find that you will need to create your own resource management classes from time to time.

For example, suppose you are using the C API to manipulate mutex objects of the mutex type to provide lock and unlock for the function:

1 void Lock // Lock Mutex pointed to by PM 2 3 void // Unlock the Mutex

To make sure you don't forget to unlock a mutex that has been locked, you need to create a class to manage the lock. The basic structure of such a class has been expressed by the RAII criterion, which is that the resource is acquired at the time of execution of the construct and released when the destructor is executed :

1 classLock {2 3  Public:4 5 ExplicitLock (Mutex *pm)6 7 : Mutexptr (PM)8 9{Lock(MUTEXPTR); }//Acquire ResourceTen  One~lock () {unlock (mutexptr);}//Release Resource A  - Private: -  theMutex *mutexptr; -  -};

The client uses the lock in a traditional RAII way:

1Mutex m;//define the mutex you need2 3 ...4 5{//Create block to define critical section6 7Lock ml (&m);//Lock the Mutex8 9...//perform critical section operationsTen  One}//automatically unlock mutex at end A  - //of block

2. What happens when you copy a resource management class?

That's fine, but what happens if a lock object is copied?

1 // Lock M 2 3 // copy Ml1 to Ml2-what should 4 5 // happen here?

The above is a more general question, and the author of every RAII class must face it: what should happen when a Raii object is copied? In most cases, you will choose from one of the following 4 possibilities:

2.1 Forbidden Copy
    • Copying is prohibited. In many cases, it is meaningless to allow RAII objects to be copied. This may be true for a class like lock, because a copy of the synchronous Primitive (synchronization primitives) is rarely meaningful. When a copy of a Raii class is meaningless, you should disallow it. Item 6 explains how you can do this: Declare the copy operation as private. For lock, it can look something like this:
1 class Private // Prohibit Copying-see 2 3  Public // Item 6 4 5 // As before 6 7 };

2.2 A resource, multiple references-using tr1::shared_ptr
    • A reference count is made to the underlying resource. Sometimes you need to keep a resource until the last object referencing the resource is destroyed. In this case, copying a Raii object should increase the reference count of the object reference resource. This is the meaning of "copy" with Tr1::shared_ptr.

Typically, the Raii class can implement copy behavior of a reference count by including a TR1::SHARED_PTR data member. For example, if lock wants to use a reference count, it can change the type of mutexptr from mutex* to tr1::shared_ptr<mutex>. Unfortunately, the default behavior of Tr1::shared_ptr is to remove the resource it points to when the reference technology is 0, which is not what we want. When we implement a mutex class, we just want to unlock and don't want to delete them. Fortunately, Tr1::shared_ptr allows you to specify your own delete ("deleter")---a function or function object, which is automatically called when the reference count is 0. (This feature does not exist in auto_ptr, it always deletes the pointer.) This is the second optional argument to the Tr1::shared_ptr constructor, so the code looks like this:

1 classLock {2 3  Public:4 5 ExplicitLock (Mutex *pm)//Init shared_ptr with the Mutex6 7: Mutexptr (PM, unlock)//To point to and the unlock func8 9{//As the deleter†Ten  One Lock(Mutexptr.Get());//See Item in "get" for info A  - } -  the Private: -  -Std::tr1::shared_ptr<mutex> mutexptr;//Use shared_ptr -  +};//instead of raw pointer

Note In this example, the lock class no longer declares a destructor. Because it's not necessary. Item 5 explains that a destructor for a class, whether compiler-generated or user-defined, automatically invokes destructors for non-static data members in the class. In this example, the non-static data member is MUTEXPTR. However, when the reference count of the mutex is 0, its destructor automatically calls the Tr1::shared_ptr-unlock. (People see the source code of the class if there is a line of comments that you do not forget the destructor, you just use the compiler default generated destructors, they will be grateful.) )

2.3 A resource, multiple copies--deep copy
    • Copy the underlying resources. Sometimes you can have as many copies of a resource as possible, and the only reason you need a resource management class is to be able to make sure that the resources are released when they are used. In this case, copying a resource management object should also copy the resources he has wrapped (wraps). That is, copying a resource management class object requires a " deep copy ."

There are a number of standard string implementations that contain pointers to heap memory, and the characters that make up the string are saved in this block of memory. When a string object is copied, both the pointer and the memory pointed to by the pointer are copied. Such a string shows a deep copy.

2.4 One resource, one quote, transfer ownership--using auto_ptr
    • Transfer ownership of the underlying resource. On rare occasions, you may want to ensure that only one Raii object points to a native (raw) resource, so when the Raii object is copied, the ownership of the resource is transferred from the copied object to the copied object. As item 13 explains, this is the meaning of copying using auto_ptr.

Copy functions can be generated by the compiler, so unless the compiler builds the version that you want (Item 5 explains the behavior of the default version), you need to implement them yourself. In some cases you may want to support the general version of these functions. These versions are described in Item 45.

3. Summary
    • Copying a Raii object requires copying the resources he manages, so the copy behavior of the resource determines the copy behavior of the Raii object.
    • The copy behavior of the ordinary Raii class is to prohibit copying and perform reference counting, but other copy behavior is also possible.

Reading notes effective C + + Item 14 copy behavior of the resource management class be cautious

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.