Objective C ++ clause 13: Object-based resource management

Source: Internet
Author: User

Resources are: once used, they must be returned to the system in the future. In addition to common memory, there are also file descriptors (File description), mutex locks, brushes in the graphic interface, and database connections.

And network socket. Considering exceptions, multiple return paths in functions, and software changes made by the program maintainer, the impact was not understood, and it was found that the special methods of resource management were insufficient.

Assume a root class investment inherited by a variety of investment types:

Class investment {...};

Let us use a factory function to supply a specific investment object:

Investment * createinvestment (); // return the Dynamic Allocation object pointing to the investment inheritance system. The caller is responsible for deleting it.

Void F ()
{
Investment * pinv = createinvestment (); // call the factory function
...
Delete pinv; // release the object specified by pinv
}

If... If there is an early return statement or an exception is thrown, the control flow will not be lucky to be deleted.

To ensure that resources are always released, we need to put the resources into the object so that the resources can be released by relying on the "Automatic calling mechanism of destructor" of C ++. The auto_ptr provided by the standard library is a special product designed for this situation. Auto_ptr is a "pointer-like" object ":

Void F ()
{
STD: auto_ptr <investment> pinv (createinvestment ());
...
} // Automatically delete pinv through the destructor of auto_ptr

1. After obtaining the resource, put it into the management object immediately. The resources returned by createinvestment are treated as the initial values of the Manager auto_ptr.

The concept of "Object-based resource management" is often referred to as "resource acquisition is initialization; raiI). Sometimes the obtained resources are assigned values (rather than initialized) A management object, but in either case, each resource is immediately put into the management object when it is obtained.

2. Management Objects use destructor to ensure resources are released. Once an object is destroyed (when the object leaves the scope), its destructor is automatically called, and the resource is released.

Because autu_ptr is automatically deleted when it is destroyed, do not let multiple auto_ptr point to the same object at the same time. To prevent this problem, auto_ptr has an unusual nature: if you copy them through the copy constructor or the copy assignment operator, they will become null, the pointer obtained by the copy operation obtains the unique right to use the resource.

STD: auto_ptr <investment> pinv1 (createinvestment ());
STD: auto_ptr <investment> pinv2 (pinv1); // now pinv2 points to the object, and pinv1 is set to null
Pinv1 = pinv2; // now pinv1 points to the object, and pinv2 is set to null

This strange replication behavior makes it impossible for its elements to perform "normal" replication behaviors such as STL containers.

The alternative to auto_ptr is reference-counting smart pointer (rcsp), which continuously tracks the total number of objects pointing

A resource that is deleted when no one points to it. Similar to garbage collection, but cannot break the cycle reference (cycle of reference, for example, two objects that are not actually used are mutually referred, so they seem to be in the "used" status ).

Tr1: shared_ptr of tr1 is an rcsp, so you can write F as follows:

Void F ()
{
STD: tr1: shared_ptr <investment> pinv (createinvestment ());
...
} // The pinv is automatically deleted by using the shared_ptr destructor.

Shared_ptr replication is much more normal.

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 are destroyed, and the objects they direct to are destroyed.

Therefore, shared_ptr can be used in STL containers and other contexts where "the unorthodox replication behavior of auto_ptr is not suitable.

Auto_ptr and shared_ptr perform the delete rather than Delete [] action in their destructor. That means using auto_ptr or shared_ptr on the dynamically allocated array is a bad idea. Because vector and string can almost always replace the dynamically allocated array. Boost: scope_array and boost: shared_array classes are classes designed for arrays similar to auto_ptr and tr1: shared_ptr.

To prevent resource leakage, use the raiI object. They obtain resources in the constructor and release resources in the destructor. Shared_ptr is a better choice than auto_ptr

Because of its intuitive copy behavior.

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.