About auto_ptr in C ++

Source: Internet
Author: User

In C ++, auto_ptr dynamically allocates objects and automatically clears objects when they are no longer needed.

 

1. the constructor and the Destructor auto_ptr obtain the ownership of an object during the constructor construction and release the object during the analysis. We can use auto_ptr to improve code security:

Int * p = new int (0 );

Auto_ptr <int> ap (p );

From then on, we don't have to worry about when to release p, or worry about memory leakage in case of exceptions.

Note the following points:

1) because the auto_ptr structure will definitely Delete the object he owns, we should note that two auto_ptr cannot have the same object at the same time. Like this:

Int * p = new int (0 );

Auto_ptr <int> ap1 (p );

Auto_ptr <int> ap2 (p );

Because both ap1 and ap2 think that the pointer p is managed by it, they attempt to delete p in the structure. The behavior of deleting the same object twice is undefined in the C ++ standard. Therefore, we must prevent the use of auto_ptr.

2) consider the following usage:

Int * pa = new int [10];

Auto_ptr <int> ap (pa );

Because the delete pointer in the destructor of auto_ptr uses delete instead of delete [], we should not use auto_ptr to manage an array pointer.

3) The explicit keyword of the constructor effectively prevents implicit conversion from a "Bare" pointer to the auto_ptr type.

4) C ++ ensures that it is safe to delete a null pointer, so we do not need to write the Destructor as follows:

~ Auto_ptr () throw ()

{

If (ap) delete ap;

}

2 Copy construction and assignment

Unlike the reference counting smart pointer, auto_ptr requires its full possession of the "Bare" pointer. That is to say, a "Bare" pointer cannot be owned by more than two auto_ptr at the same time. Therefore, during the copy construction or value assignment operation, we must make special processing to ensure this feature. The auto_ptr method is "ownership transfer", that is, the source object to copy or assign values will lose ownership of the "Bare" pointer. Therefore, unlike the general copy constructor, the assign function is different, the copy constructor of auto_ptr. The parameters of the value assignment function are references rather than const references ). of course, an auto_ptr cannot have more than two "Bare" pointers at the same time. Therefore, the target object to copy or assign values will first release the original object.

Note:

1) because an auto_ptr is copied or assigned a value, it has lost ownership of the original object. At this time, the dereference operation on this auto_ptr is insecure. As follows:

Int * p = new int (0 );

Auto_ptr <int> ap1 (p );

Auto_ptr <int> ap2 = ap1;

Cout <* ap1; // error. At this time, ap1 has only one null pointer in the hand.

This situation is concealed when auto_ptr is passed as a function parameter by value, in the process of calling a function, a local object is generated in the function scope to receive the passed auto_ptr (copy structure). In this way, the input real parameter auto_ptr loses its ownership of the original object, and the object will be deleted by the partial auto_ptr when the function exits. As follows:

Void f (auto_ptr <int> ap) {cout <* ap ;}

Auto_ptr <int> ap1 (new int (0 ));

F (ap1 );

Cout <* ap1; // error. after calling the f (ap1) function, ap1 no longer owns any objects.

Because this situation is too concealed and error-prone, auto_ptr must be avoided as a function parameter passing by value. Maybe you may think of using the pointer or reference of auto_ptr as a function parameter. But if you think about it, we don't know what the input auto_ptr has done in the function, if some of these operations cause them to lose ownership of the object, this may still lead to a fatal execution error. It may be a good choice to pass auto_ptr in the form of const reference.

2) We can see that both the copy constructor and the value assignment function provide a member template to implement implicit conversion of auto_ptr without overwriting the "Orthodox" version. We have the following two classes:

Class base {};

Class derived: public base {};

The following code can be used to implement implicit conversion from auto_ptr <derived> to auto_ptr <base>, because derived * can be converted to base *.

Auto_ptr <base> apbase = auto_ptr <derived> (new derived );

3) Because auto_ptr does not have value semantic, auto_ptr cannot be used in stl standard containers.

The so-called value semantics refers to the type that meets the following conditions (suppose there is Class ):

A a1;

A a2 (a1 );

A a3;

A3 = a1;

Then www.2cto.com

A2 = a1, a3 = a1

Obviously, auto_ptr does not meet the above conditions, but we know that stl standard containers require a large number of copy assignment operations, and assume that the operation type must meet the above conditions.

3. Pull operation (dereference)

The pull Operation has two operations: one is to return the reference of the objects it owns, and the other is to call the members of the objects it owns through auto_ptr. For example:

Struct

{

Void f ();

}

Auto_ptr <A> apa (new );

(* Apa). f ();

Apa-> f ();

Of course, we must first ensure that this smart pointer does have an object. Otherwise, the action of this operation is that the pull of the NULL pointer is undefined.

4 auxiliary functions

1) get is used to explicitly return the Object Pointer owned by auto_ptr. We can find that the auto_ptr provided by the standard library does not provide implicit conversion from the "Bare" pointer to auto_ptr (the constructor is explicit ), it also does not provide implicit conversion from auto_ptr to "Bare" pointer. In terms of usage, it may not be so flexible. Considering the security brought by it, it is worth noting.

2) release, used to transfer ownership

3) reset, used to receive ownership. If the auto_ptr that receives the ownership already has an object, it must be released first.

5 Special Conversions

Here we provide an auxiliary class auto_ptr_ref for Special conversion. According to the standard explanation, the function of this class and the following four functions is: We can copy and assign values to non-const auto_ptrs, you cannot copy or assign values to const auto_ptrs. I cannot understand the meaning of these two sentences very accurately, but according to our observation and experiment, we should be able to understand this: without the code, we could have copied and assigned the auto_ptr of non-const and the auto_ptr function of prohibiting copying and assigning values to const, but we could not copy or assign a temporary auto_ptr (right value ), the auxiliary Code provides some conversions so that we can copy and assign temporary auto_ptr values, but it does not make const auto_ptr copies and assigns values. As follows:

Auto_ptr <int> ap1 = auto_ptr <int> (new int (0 ));

Auto_ptr <int> (new int (0) is a temporary object with a right value. The normal copy constructor can certainly copy the right value, because the parameter category must be a const reference, but we know that the copy function of auto_ptr has the parameter type as reference, in order to make this line of code pass, we introduce auto_ptr_ref to convert the value from the right to the left. The process is as follows:

1) ap1 needs to copy auto_ptr <int> (new int (0) to construct itself.

2) auto_ptr <int> (new int (0) as the right value cannot match the existing two copy constructor parameter types, nor can it be converted to this parameter type.

3) The secondary copy constructor auto_ptr (auto_ptr_ref <T> rhs) throw () is found ()

4) try to convert auto_ptr <int> (new int (0) to auto_ptr_ref <T>

5) The type conversion function operator auto_ptr_ref <Y> () throw () is found. The conversion is successful and the copy is successful.

In this way, an indirect class is used to successfully copy and construct the right value (temporary object)

At the same time, this helper method will not copy const auto_ptr because in step 1, the conversion function of this type is non-const. We know that, the const object cannot call non-const members, so the conversion fails. Of course, there is a problem here. If you comment out the code for the secondary conversion, the code in this line may still be compiled successfully. Why? After debugging, we can find that the constructor is called only once, and the copy constructor is not called because the compiler has optimized the code. This type of optimization is called returned value optimization, which can effectively prevent the construction of meaningless temporary objects. Of course, the premise is that your compiler must support returned value optimization.


From the trace

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.