Intelligent pointer auto_ptr Parsing in C + +

Source: Internet
Author: User
Tags truncated

Auto_ptr in C + + is a class that can be used like a pointer. Use Auto_ptr to include header file # include <memory>

For example:auto_ptr<string> PS (new string ("Hello")), you can use it like a pointer, so cout << ps->size () <<endl;uto_ The advantage of PTR is that programmers do not need to delete manually, which is great for programmers who forget delete, because sometimes delete is really easy to forget, and memory leaks are hard to find errors. The garbage collector mechanism is used in Java, which avoids the problem of memory leaks to a large extent.

Example:

#include <iostream> #include <memory>using namespace Std;class a{public:a (int x = 0): m_x (x) {cout << "A" "<< Endl;} ~a () {cout << "A destructor" << Endl;} void print () const{cout << m_x << Endl;} Private:int m_x;}; void Test () {A * pa = new A (123);p a->print ();d elete PA;} int main () {cout << "main function Begins" << endl;test (); cout << "main function End" << Endl;}
In the above code, in the test function if we forget the delete, that is, the delete pa comment out, the class A destructor can not be called. In the test function, a * PA is a local pointer variable, and the function end PA is released, but the memory space that the PA points to cannot be freed. So in order to avoid a programmer forgetting to delete the memory leak, Auto_ptr's idea is that the PA points to the memory space accompanying the PA release is released. Imagine if the PA is a class type and the PA is allocated on the stack memory, then the PA's destructor is bound to be called when the PA is released. Then, in the PA class of the destructor to release the PA point to the heap memory space, then there is no manual delete, PA is auto_ptr.


So if we comment out the A * pa = new A (123) in the code above, plus the auto_ptr<a> PA (new A (123)), and the delete PA is commented out, you will find that the Class A destructor is called.

Take a look at some of the source code implementations of AUTO_PTR, and first focus on the constructors and destructors of Auto_ptr.

Template<class _ty>
Class Auto_ptr
{ Wrap an object pointer to ensure destruction
Public
typedef auto_ptr<_ty> _MYT;
typedef _ty ELEMENT_TYPE;


Explicit Auto_ptr (_ty *_ptr = 0) _throw0 ()
: _myptr (_PTR)
{ Construct from Object pointer
}


Auto_ptr (_myt& _right) _throw0 ()
: _myptr (_right.release ())
{ Construct by assuming pointer from _right auto_ptr
}

/* The code here is truncated */

~auto_ptr () _noexcept
{ //Destroy the object
Delete _myptr;
}

/* Here the code is truncated */

Private
_ty *_myptr; //The Wrapped object pointer


You can see that auto_ptr is using a class template that can accept parameters of any reference type. Take auto_ptr<string> PS (new string ("Hello")) as an example, when executing this sentence, the first constructor of Auto_ptr is called, and the address of new is given to _ty *_myptr, where _ Ty has been instantiated as a string. The constructor also adds explicit to prevent the type conversion, which means that writing auto_ptr<string> PS = new string ("Hello") will cause an error. And you can see that the last destructor will delete the new memory, so you don't have to manually release the programmer when using AUTO_PTR.


Atuo_ptr's flaws:

Disadvantage 1:auto_ptr lacks copy semantics.

In C + +, there are typically three copies of contacts, deep copy, shallow copy, transfer copy.

A, shallow copy:

is a byte-by-bit copy, the default copy constructor is a shallow copy. Assigning a pointer directly to another pointer causes two pointers to point to the same block of memory.

b, deep copy

One pointer is assigned to another pointer while the memory is processed, and two pointers have their own independent memory space.

C. Transfer copy

Once a pointer is assigned to another pointer, the previous pointer (the source pointer is assigned a null value).

What happens when Auto_ptr uses a copy of the transfer semantics? Let's change the test function of the first example to look like this.

void Test () {/*PA itself is freed, a mechanism that causes the release of the PA to release the heap memory so that a normal pointer is no longer saved to the PA, and a class is used to save the *///a * pa = new A (123);auto_ptr<a> PA (New A ( 123));p A->print (); Delete pa;/* the problem of smart pointers, lack of copy semantics, the normal pointer certainly no problem */auto_ptr<a> PB = pa;//copy construction pb->print ();/* Segment Error */pa->print ();}

Then the last word pa->print () execution will have a segment error, because this time the PA is empty, through the null pointer to access the inevitable segment error. This is not the same as the access to the normal pointers, because they are copied in a special way.

Of the three copy semantics above, why is auto_ptr not using shallow copy semantics or deep copy semantics? If you use the shallow copy semantics, then the issue of Doulle free on the same pointer will inevitably appear when releasing, that is, releasing two times. What about a deep copy? is to give a copy of the pointer to a separate memory space, the problem is that it does not conform to the logic of the pointer copy, because one pointer to another pointer, two pointers to the same piece of memory, so do not consider the deep copy, and finally chose a transfer copy of the way.


Disadvantage 2: Cannot manage an array of objects

Design function Test2:

/* Smart pointer problems managing multiple Objects */void test2 () {auto_ptr<a> PA (new a[3]);//core dump, error mapping/* Why smart pointer cannot manage object array */}
Why can't auto_ptr manage an array of objects?

Allocate multiple objects at one time we have to use delete[] to release, or we will go wrong. The final question is actually the difference between delete and delete[].

Delete is used to release a single object, get the address of the object, and call free, and the allocation of the object array is different, in addition to allocating the required size of the heap memory space, the beginning of this heap of memory is also allocated 4 bytes of space to hold the number of allocated objects, The first four bytes must be included in the release, delete[] at the time of release, the resulting address minus 4, so that the initial address, so that the release is the correct release, and the release of delete did not reduce the operation of 4, so it is not properly released.

You can see that only delete is released in Auto_ptr's destructor, so an array of objects must be wrong.


The improved AUTO_PTR enables it to manage an array of objects. We take the object array special processing, in this case using delete[] to release, the use of class template special processing;

An improved version that can manage an array of objects

#include <iostream>using namespace Std;template<typename t>class autoptr{public:explicit AutoPtr (T*p = NULL): M_p (P) {}~autoptr () {if (m_p) delete m_p;} /* Copy Construction */autoptr (autoptr<t>& that): M_p (That.release ()) {}/* copy Assignment */autoptr& operator= (autoptr<t> & that) {if (&that! = this) reset (That.release ()); return *this;} t& operator* () Const{return *m_p;} t* operator-> () Const{return &**this;//return this->m_p;} Private:t* release () {t* p = m_p;m_p = Null;return p;} /* Reset m_p*/void Reset (t* p) {if (P! = m_p) {delete m_p;m_p = P;}} T * m_p;};/ * Special version, all rewritten in the way */template<typename t>class autoptr<t[]>{public:explicit autoptr (t*p = NULL): m_p (p) {}~ Autoptr () {if (m_p) delete[] m_p;} /* Copy Construction */autoptr (autoptr<t>& that): M_p (That.release ()) {}/* copy Assignment */autoptr& operator= (autoptr<t> & that) {if (&that! = this) reset (That.release ()); return *this;} t& operator* () Const{return *m_p;} t* operator-> () Const{return &**this;//return This-> m_p;} private:/* the implementation function of transfer copy semantics 1, set the pointer to null, and then return */t* release () {t* p = m_p;m_p = Null;return p;} /* Reset m_p*/void Reset (t* p) {if (P! = m_p) {delete m_p;m_p = P;}} T * m_p;}; Class a{public:a (int x = 0): m_x (x) {cout << "A construction" << Endl;} ~a () {cout << "A destructor" << Endl;} void print () const{cout << m_x << Endl;} Private:int m_x;}; void Test () {autoptr<a> PA (new A (123));p A->print ();(*pa). Print (); autoptr<a> PB = Pa;pb->print ();p A = PB; (*PA). print ();} void Test2 () {autoptr<a[]> p (new a[3]); int main () {test (); Test2 ();}

The above code is improved not only to make auto_ptr have the original function, but also to manage the object array, the object array has been made special processing.

It is worth explaining that the smart_ptr pointer, which appears in c++2011, really achieves "intelligence", which can not only manage the object array, but also has the copy semantics of pointers, and SMART_PTR uses the special processing in the management object array, and uses the technique of setting counter in processing copy semantics. There is no detailed explanation here.




Intelligent pointer auto_ptr Parsing in C + +

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.