(Proactive C ++) Chapter 3 Resource Management)

Source: Internet
Author: User
5.1 clause 13: Use object to manage resource)

Manage resources as objects.
In general, who applies for resources and who is responsible for releasing them. As follows:
Class investment {};
Void F
{
Investment * pinv = new investment (); // call to create a class
...
Delete pinv; // release resources
}
To ensure that the requested resource is always released, we need to put the resource into the object. When the control flow leaves F, the destructor of this object will automatically release those resources. In fact, this depends on the automatic calling mechanism of the c ++ destructor to ensure that resources are released.
Void F ()
{
STD: auto_ptr <investment> pinv (new investment (); // The destructor of auto_ptr automatically deletes pinv.
...
}
Auto_ptr is a smart pointer and management object. It uses destructor to ensure resources are released. Because auto_ptr is automatically deleted when it is destroyed, be sure not to let multiple auto_ptr point to the same object at the same time. Auto_ptrs has an unusual nature. If you assign values to them through the copy constructor or the copy assignment operator, they become null, And the copied pointer will obtain the unique ownership of the resource.
STD: auto_ptr <investment> pinv1 (new investment ());//
STD: auto_ptr <investment> pinv2 (pinv1); // now pinv2 points to the object, while pinv1 is set to null
Pinv1 = pinv2; // now pinv1 points to the object, while pinv2 is set to null
Example 5-1-1 copying function of auto_ptr

Injection. STL containers require that their elements perform normal replication. Therefore, these containers are not allowed to use auto_ptr.
The alternative of auto_ptr is to reference the counting smart pointer, which is also a smart pointer.
Void F ()
{
// Use the shared_ptr destructor to automatically delete pinv.
STD: tr1: shared_ptr <investment> pinv (new investment ());
...
}
Shared_ptr Replication
STD: tr1: shared_ptr <investment> pinv1 (new investment ());//
STD: tr1: shared_ptr <investment> pinv2 (pinv1); // now pinv1 and pinv2 point to the same object

Pinv1 = pinv2; // same as above, no change
Example 5-1-1 behavior of the shared_ptr copying function
Notes
Auto_ptr and tr1: shared_ptr both perform the delete action in their destructor instead of the Delete [] action.

5.2 Clause 14: copying behavior (think carefully about copying behavior in Resource-managing classes)

Copying behavior is preferred in resource management.
If you need to design a class to manage resources, its basic structure is governed by the raiI Code (the time when resources are acquired is the time of initialization), that is, "resources are obtained during the construction and released during the analysis. "

Class lock
{
Public:
Explicit lock (mutex & PM): mutexptr (pm)
{
Lock (mutexptr );
}
~ Lock () {unlock (mutexptr);} // release resources
PRIVATE:
Mutex * mutexptr;
};
Mutex m; // defines the mutex you need
...
{// Create a block to define the critical section
Lock M1 (& M); // lock
... // Perform the critical section operation
} // Automatically unlock the mutex at the end of the block
// If the Lock Object is copied
Lock M1 (& M); // lock
Lock m2 (M1); // copy
Example 5-2-1 an unusually safe and efficient operator = implementation
When a raiI object is copied, the following two possibilities are generally made:
Prohibit Replication
For example
Class lock: Private uncopyable // prohibit copying
{
Public:
... // As before
};
Use reference notation for underlying resources.

5.3 Clause 15: Provide access to original resources in resource management (provide access to raw resource in resource-management classes)

Assume that a smart pointer, such as auto_ptr and tr1: shared_ptr, is used to save the call result of new investment.
STD: tr1: shared_ptr <investment> pinv (new investment ());
However, if you want to use a function to process the investment object, consider the following:
Int daysheld (const investment * PI); // returns the number of days invested
Int days = daysheld (pinv); // Error
Daysheld requires the investment * pointer. What you pass to it is an object of the type STD: tr1: shared_ptr <investment>. However, auto_ptr and tr1: shared_ptr both provide a get member function to execute display conversion, that is, they will return the original pointer inside the smart pointer:
Int days = daysheld (pinv. Get (); // correct

Just like all smart pointers, auto_ptr and tr1: shared_ptr also reload the pointer dereferencing operators (operator-> and operator *), they allow conversion to the original pointer at the bottom.

Class Investment
{
Public:
Bool istaxfree () const;
};
STD: tr1: shared_ptr <investment> PI1 (new investment ());
Bool taxable1 =! (PI1->Istaxfree ())
// Access resources through operator->

STD: auto_ptr <investment> Pi2 (new investment ());
Bool taxable2 =! (* Pi2).Istaxfree ())
// Access resources through operator *

Example 5-3-1 Intelligent pointer overload operators (operator-> and operator *)
Access to the original resource may be converted by display or implicit conversion. However, Explicit conversions are safer.

5.4 clause 16: use the same form (use the same form in corresponding uses of new and delete) to use new and delete in pairs)

Skipped. For more information, see Objective C ++ p73.

5.5 Clause 17: place a newed object in a smart pointer using an independent statement (store newed objects in smart pointers in standalone statement)

There are two methods as follows:
Int priority ();
Void processwidget (STD: tr1: shared_ptr <widget> PW, int priority );
Use as follows:
Processwidget (STD: tr1: shared_ptr <widget> (new widget), priority ());
The preceding call may expose resources. Before the compiler generates a processwidget call code, it must calculate the real parameters that are passed. The first real parameter consists of two parts:
1) execute the "new widget" expression
2) Call the STD: tr1: shared_ptr constructor.

Therefore, before calling processwidget, the compiler should first do three things:
1) Call priority ()
2) Execute "new widget"
3) Call the STD: tr1: shared_ptr constructor.

The sequence in which the C ++ compiler completes the preceding three steps is uncertain. If the order is as follows:
1) Execute "new widget"
2) Call priority ()
3) Call the STD: tr1: shared_ptr constructor.

If the call to priority () fails, but the new widget succeeds, but it has not been placed in STD: tr1: shared_ptr, this will cause resource leakage.
Correct Solution:
STD: tr1: shared_ptr <widget> Pw (new widget );
Processwidget (PW, priority ());

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.