Smart pointer (I): STL auto_ptr implementation principle

Source: Internet
Author: User

A smart pointer is actually a class, which encapsulates a pointer. What is its usefulness?

Pointer and memory

When it comes to pointers, memory is involved.Memory is allocated in the stack. The system is responsible for releasing the memory after it is used up.. If it is a custom type, your destructor will be automatically called.

HoweverHeap memory is allocated, that is, with malloc or new. It can only be automatically and manually released using free or delete.. Therefore, when heap is used, memory leakage is very likely to occur due to poor processing (the memory has not been released ). or, if you delete the object once, but do not assign it a value of 0, and then delete it again, leading to undefined behavior.

So you wantIf the system manages your heap region like a stack, you don't have to worry about how much memory allocation and release are. In fact, Java and C # are doing this.. You can also manage the heap region (all user-defined types are instantiated and the heap region is used to obtain the memory. it does not provide the pointer function. if you want to release the memory, you will not be given this opportunity. JVM or CLR will automatically release unnecessary memory in the background. of course, the efficiency is not as high as that of manual release .)

Assume thatThere is a pointer pointing to a allocated memory. The smart pointer encapsulates the pointer and automatically releases the memory when it is used up (through the destructor of the smart pointer class ). in this way, you don't have to worry about not releasing the memory.Of course, it doesn't mean that you can use smart pointers, just like using Java and C #, without worrying about memory problems. There are still many problems when using smart pointers.

It is said that the JVM and CRL are also implemented using (C and C ++). I don't know if it is useful for smart pointers.

 

Intelligent pointer implementation

What if you want to encapsulate a pointer on your own? Here is a first draft.

1. Simplified Version

Template <class T>

Class my_auto_ptr{

Public:

T * m_ptr; // encapsulated pointer

Public:

My_auto_ptr (T * P): m_ptr (p) {}// Constructor

~ My_auto_ptr () {Delete m_ptr;} // destructor

}

The above is naturally the lite version, with only one member variable, constructor and analysis function. However, it can be used even though it is simple. For example:

My_auto_ptr <int> myptr (New int (88); // equivalent int * IP = new int (88); but you have to manually delete the IP address; you do not need to manually delete the data with a smart pointer.

Cout <* myptr. m_ptr; // equivalent to cout <* IP;

 

2. Improved Version (overload operators enable class usage like pointers)

The simplified version above is quite troublesome to use. We want to encapsulate the pointer class and use it as well as the pointer itself. Therefore, we need to reload the operators such as-> and *.

Template <class T>

Class my_auto_ptr{

PRIVATE:

T * m_ptr; // encapsulated pointer

Public:

My_auto_ptr (T * P): m_ptr (p ){}

~ My_auto_ptr () {Delete m_ptr ;}

T & operator * () {return * m_ptr ;}

T * operator-> () {return m_ptr ;}

}

Now my_auto_ptr can be like a pointer.

My_auto_ptr <int> MP (New int (88); // equivalent int * IP = new int (88 );

Int num = * MP; // equivalent int num = * IP;

Suppose there is such a class struct Arwen {void test () {cout <"I am Arwen" <;}

Then my_auto_ptr <Arwen> MP (New Arwen); // equivalent Arwen * IP = new Arwen;

MP-> test (); // equivalent IP address-test ();

 

 

3. Improved Version (copy Construction)

A perfect class usually involves copying and constructing some operations. You can also use another smart pointer class as the parameter of the constructor, or assign a value to a class through =.

Template <class T>

Class my_auto_ptr {

PRIVATE:

T * m_ptr;

T * getptr () {// used to construct a value assignment

T * TMP = m_ptr;

M_ptr = 0;

Return TMP;

}

Public:

Explicit my_auto_ptr (T * p = 0): m_ptr (p ){}

~ My_auto_ptr () {Delete m_ptr ;}

T & operator * () {return * m_ptr ;}

T * operator-> () {return m_ptr ;}

 

My_auto_ptr (my_auto_ptr & MP) {// copy the constructor

M_ptr = mp. getptr (); // After the MP is copied, its original pointer is invalid.

}

My_auto_ptr & operator = (my_auto_ptr & AP) {shape assignment operator

If (AP! = * This)

{

Delete m_ptr;

M_ptr = ap. getptr ();

}

Return * this;

}

 

Void reset (T * P) {// pointer reset, equivalent to pointing the pointer to another place

If (P! = M_ptr)

Delete m_ptr;

M_ptr = P;

}

};

 

Example:

FalseStruct Arwen {

Int age;

Arwen (int gg): Age (gg ){};

};

 

Void main ()

{

My_auto_ptr <Arwen> myptr (New Arwen (24 ));

Int num = myptr-> age; // correct

 

My_auto_ptr <Arwen> ptrone (myptr); // copy the structure

// Num = myptr-> Age

Num = ptrone-> age; // correct

 

My_auto_ptr <Arwen> ptrtwo = ptrone;

// Num = ptrone-> Age

Num = ptrtwo-> age; // correct

 

Arwen * parwen = new Arwen (88 );

Ptrtwo. Reset (parwen );

Num = parwen-> age; // The value here is 88, not the previous 24

 

Return 0;

}

 

 

Auto_ptr Defects

The my_auto_ptr I implemented above basically implements all the core functions of auto_ptr. we can see a major defect from it. we can see that after the complex constructor and the operator = assign value, the original smart pointer object becomes invalid. only new smart pointer objects can be used effectively. in a professional point, ownership is transferred. the encapsulated Pointer Points to a memory block, which is like an exclusive property. When the block is constructed through replication and passed to another smart pointer object through = assignment, the original object loses its ownership of the memory area. that is to say, only one smart pointer object can point to that memory area at any time, and two objects cannot point to that memory area at the same time.

In this way, auto_ptr cannot be used as an element of the STL container. Why? Because the container often copies values, assign a container object to another object directly. after that, both container objects can be used. if it is auto_ptr, it is clear that only one value can be assigned, and the other is completely scrapped. for example, if you have a variable auto_ptr <int> aP (New int (44), and the AP is put into a container, the AP will be useless.

But there is no way,Before the C ++ 11 standard, we currently use the 98 standard. STL only contains the auto_ptr smart pointer. In the 11 standard, there are three other smart pointers besides auto_ptr.:

 

Unique_ptr

Smart pointer with unique object ownership Semantics

Only one master pointer can be used for STL containers.

Shared_ptr

Smart pointer with shared object ownership Semantics

Shared pointer

Weak_ptr

Weak reference to an object managed by STD: shared_ptr

Weak reference pointer

Smart pointer (I): STL auto_ptr implementation principle

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.