"Effective C + +" Chapter 3rd resource Management (1)-Reading notes

Source: Internet
Author: User
Tags mutex

Chapter Review:

The 1th chapter of effective C + + makes himself accustomed to c++-reading notes

Effective C + + 2nd structure/destructor/assignment operation (1)-Reading notes

Effective C + + 2nd structure/destructor/assignment operation (2)-Reading notes

"Effective C + +" Chapter 3rd resource Management (1)-Reading notes

"Effective C + +" 8th custom new and delete-reading notes

Memory is just one of the many resources you have to manage. Other common resources include file descriptors, mutex (mutex locks), glyphs and brushes in the graphical interface, and network sockets. No matter what kind of resource, it is important that you return it to the system when you no longer use it.

Article 13: Managing Resources with objects

Below is a investment inheritance system:

class Investment {...};

Investment is the root class, and the object to get the investment system is through the factory function:

// The return pointer points to the investment inheritance system dynamic allocation object

Obviously, after Createinvestment is used, it is the responsibility of the caller to delete the returned pointer to dispose of the object. Assume that the function f () is responsible for this behavior:

void f () {    *PINV = createinvestment ();     .... Delete PINV;}

But there are at least a few situations where F () cannot delete the Createinvestment object:

(1)... The zone has a premature return statement, causing the delete to not execute.

(2)... Zone throws an exception, the control flow does not turn to delete.

When we delete, we reveal not just the memory that contains the investment object, but also any resources it holds.

To ensure that the resources returned by Createinvestment () are always released, we need to put the resources inside the object, and when the control flow leaves F (), the object's destructor will automatically release those resources. The auto_ptr provided by the standard library is a "Class pointer object", a smart pointer whose destructor automatically calls delete on the object it refers to.

The following is a revised version of F ():

void f () {    std::auto_ptr<Investment> PINV (Createinvestment ());            // automatically delete Pinv by Auto_ptr's destructor     ...}

F () illustrates two important aspects of managing resources with objects:

(1) The resource is immediately placed in the management object.

The concept of resource management objects is often referred to as "the timing of resource acquisition is the time of initialization" (Resource acquisition is initialization, RAII). Each resource is immediately placed into the management object while it is acquired.

(2) Management objects use destructors to ensure that resources are released.

No matter how the control flow leaves F (), once the object leaves the scope (the object is destroyed), its destructor is called and the resource is freed.

Note: because auto_ptr is destroyed automatically when it is deleted, do not allow multiple auto_ptr to point to an object at the same time. To prevent this problem, Auto_ptr has a good property: If you copy them by using the copy constructor or the copy assignment operator, they will become null, and the copied pointer will take the resource's sole weight.

Std::auto_ptr<investment> PInv1 (createinvestment ()) std::auto_ptr<Investment> pInv2 (PINV1);            // PInv2 points to the object, PINV1 is set to nullPINV1 = pInv2;                                    // pInv1 point to Object, PINV2 is set to null

It is because the Auto_ptr object has a "non-normal" copy nature, so it cannot be used in STL container elements and so on.

An alternative to auto_ptr is the reference counting smart pointer (reference-counting smart pointer (RCSP)). RCSP can track how many objects are pointing to a resource and automatically delete the resource when no one points to it. RCSP provides behavior similar to garbage collection, but it cannot break the ring reference, for example, two objects that have not been used are referred to each other as if the object is still in the "used" state.

TR1 's tr1::shared_ptr is a new way to Rcsp,f ():

void f () {    std::tr1::shared_ptr<Investment> PINV (Createinvestment ()); ...}

The new version of F () is almost identical to the use of auto_ptr, but the copy behaves normally:

void f () {    ...    Std::tr1::shared_ptr<Investment> pInv1 (Createinvestment ());    Std::tr1::shared_ptr<Investment> pInv2 (PINV1);            // PInv1 and PInv2 point to the same object    PINV1 = PInv2;                                            // PInv1 and PInv2 point to the same object     ...}

Because the replication behavior of shared_ptr is normal, it can be used in the case of STL containers and other auto_ptr where abnormal replication behavior does not apply.

Special Note:both auto_ptr and shared_ptr do a delete in the destructor instead of delete[]. So the following actions are very wrong:

STD::AUTO_PTR<STD::string> APs (new std::string[ten]); STD::TR1:: shared_ptr<int> SPI (newint[1024x768]);

There is no such auto_ptr or tr1::shared_ptr designed specifically for C + + dynamically allocated arrays because vectors and strings can always replace dynamic arrays, which is your first choice.

Please remember:

(1) to prevent resource leaks, use the Raii object, which obtains resources in the constructor and frees resources in destructors.

(2) two commonly used Raii class are: Tr1::shared_ptr and auto_ptr. The former is the best choice because its copy behavior is more normal. Copy of auto_ptr causes the copied object to point to null.

Article 14: Beware of copying behavior in resource management classes

Not all resources are heap-based, and smart pointers such as auto_ptr and tr1::shared_ptr do not always apply. Examples are as follows:

There are two functions for handling mutex mutex objects:

void Lock (Mutex *pm);            // Lock the mutex that the PM points to void unlock (Mutex *pm);            // Unlock

To ensure that you do not forget to unlock, you can create a class management lock, which is dominated by RAII, which is "resources are obtained during construction and released during destruction."

class lock{public:    explicit Lock (Mutex *pm): mutexptr (PM)    {         Lock (mutexptr);    }     ~Lock ()    {        unlock (mutexptr);    } Private :      *mutexptr;};

This is how the customer uses:

Mutex m;                    // to define the required mutex {...    Lock ml (&m);           // Lock Mutex ...}                             // Auto Unlock

It is possible to use this. But what if the copy happened? What happens when a Raii object is copied?

Lock ml1 (&m); Lock ML2 (ML1);

There are four possible types:

(1) Prohibit copying.

Many times it is not reasonable to allow RAII objects to be copied.

(2) Use the reference counting method for the underlying resource.

Sometimes we want to save resources until their last user is destroyed. This is how tr1::shared_ptr is handled.

Note:The default behavior of Tr1::shared_ptr is that when the reference count is 0 o'clock to delete its object, we want to release the lock instead of deleting it. We can specify a "delete", which is a function that will be called when the number of references is 0. Auto_ptr does not have this nature, it always removes its pointer.

The changed version is:

class lock{public:    explicit Lock (Mutex *pm): Mutexptr (PM, unlock)        //  unlock is the delete     {        lock(mutexptr).  Get());    } Private :     std::tr1::shared_ptr<Mutex> mutexptr;            // replace Raw_pointer} with shared_ptr;

Note: This lock class does not require a destructor, because the compiler automatically calls the Mutexptr destructor, and when the reference count is 0 o'clock, the delete is called automatically.

(3) Copy the bottom resource

You can have any number of copies for a single resource. This is the copy that is deep copy.

(4) Transfer of ownership of bottom resources

You may want to always have only one Raii object pointing to a raw recource even if the Raii object is copied. It is the ownership of resources that is transferred from the copied to the target. So auto_ptr.

Note:the copying function (including the copy constructor and copy assignment operator) is likely to be created by the compiler, so unless the compiler version does what you want to do, you write them yourself.

Please remember:

(1) copying a Raii object must replicate the resources it manages, so the copying behavior of the resource determines the copying behavior of the Raii object.

(2) the common Raii class copying behavior is: Prohibit copying, use reference count. Other behaviors may also be implemented.

"Effective C + +" Chapter 3rd resource Management (1)-Reading notes

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.