The unique_ptr of c++11

Source: Internet
Author: User

The original address is : http://www.drdobbs.com/cpp/c11-uniqueptr/240002708

Added a lot of new features in the C++11, unique_ptr a solo, for the dynamic allocation of memory objects, it is simple and effective. Although it's not everything, it's good enough: you can manage dynamically allocated objects with simple syntax.


Basic syntax:

Unique_ptr<t> is a template class, you can easily construct a Unique_ptr object, as follows:

Std::unique_ptr<foo> p (new foo (42));

Once constructed, you can manipulate objects as if they were normal pointers. The operator* and operator-> operators, for example, work the same as you would expect.


Just as you can use the Unique_ptr class as you would with a generic pointer, the most important thing is that you can unique_ptr automatically destroy the object when it goes out of scope. You don't have to worry about forgetting the delete at an exit in the scope to cause a memory leak, and it can automatically destroy objects even after an exception occurs.


unique_ptr and Containers :

So far, everything is lucky, according to the standard C + + syntax You can also implement the above functions, in fact, auto_ptr this unfortunate person (C++11 has abandoned it) is able to achieve the above functions, as a RAII wrapper.

No, auto_ptr does not work properly, and even for some basic operations, Auto_ptr's performance is unsatisfactory. For example, if you need to create a container that holds auto_ptr, then this will be a big problem.


Add: Regarding the relationship between objects and containers, I have written a simple code to understand:

Class A{public:    A () {cout << "a ctor called ..." << Endl;}    A (const a&) {cout << "A copy ctor called ..." << Endl;}}; int main (void) {    vector<a> vec;    for (int i=0;i<5;++i)    {        cout << "i =" << i << Endl;        Vec.push_back (A ());  Constructs the object and copies the object. See the following code for the result of the Operation    }    return 0;}

The result of the above code is:


As you can see, the copy constructor is called in the execution result of the above code.


[Continue] Step into the subject:

C++11 added rvalue references (rvalue reference) and move semantics (move semantic) to address these issues. Fortunately, the unique_ptr can be stored in a container, even if the container is resize and the move has the correct semantics. And when the containers are destroyed, the resources managed by these pointers can also be destroyed normally.


Uniqueness and move semantics:

What does the word unique mean? As it is literally, when you create a unique_ptr, you claim that the pointer is unique, that there is no ambiguity, that only you can have it, and that no one else will be able to copy it inadvertently.

For example, for a generic pointer, there is the following code:

Foo *p = new Foo ("useful object");

Make_use (P); The argument to the Make_use function is an object pointer

Here, I assign an object and have a pointer p pointing to it, what happens to the pointer p when I call the Make_use function? Will make_use make a copy of the pointer? Will the memory be freed after the call is complete? Or is it simply borrowed for a moment and the pointer is returned intact, allowing the caller to free up space?


One of the questions we can't answer is because C + + itself doesn't make any promises about how to use pointers, you can only fix them by looking at your own code and looking at your own memory and documentation.


Fortunately, with unique_ptr, these problems are not a problem, if you pass a pointer to another routine (right when the function is understood). You don't make a copy of the pointer (because it's unique), and even if you do, the compiler doesn't agree.


The owner of the pointer:

Let's start with a simple example: Create a unique_ptr and store it in a container. As a novice of unique_ptr, you may write the following code:

std::unique_ptr<foo> q (new foo); V.push_back (q);

This seems reasonable, but doing so will allow me to enter a gray area: Who is the owner of the pointer, and will the container release the pointer at some point in its life cycle? Or does it have to be created by the creator to release it yourself?


In the face of these entanglements, unique_ptr forbids such code. Compiling such code will result in a compilation error.


Anyway, the problem here is that we only allow one copy of the pointer. If you want to hand the object to another object, you must call the Move function, which means you must discard the object's ownership.

Such as:

V.push_back (Std::move (q));

After executing the above statement, Q has become empty, because Q has given up ownership of the object, giving ownership to the container.


Move semantics can be used wherever you need to create a "rvalue reference". For example, the following code:

return q;

Returning a unique_ptr does not require any special code to complete.

Also, creating a temporary object for a function that requires UNIQUE_PTR does not require special handling. Such as:

Process (std::unique_ptr<foo> (new foo (41)));


Legacy Code: The old program, in fact, is compatibility.

When you are using UNQIUE_PTR. You find that what you need now is a bottom-level pointer, then there are two ways:

Do_something (Q.get ());          Retain Ownershipdo_something_else (Q.release ()); Give up ownership

The Get function is not transferred to the owning property. Therefore, in most cases the GET function is not advocated for use. Because once you release the real pointer of the UNIQUE_PTR package to the function, it is difficult to control what the function actually does with the pointer. That means you have to be cautious about your function to ensure that the function simply borrows the pointer.

And the release function is a more reliable way, when you call release to the same as the pointer Q, in fact, you have already declared that the object is not my tube, now is yours.


When your code is written in a more mature way, it will not appear more frequently.

Also, when Unique_ptr is passed to the function as a reference object, it is as follows:

void Inc_baz (std::unique_ptr<foo> &p) {    p->baz++;}

Because it is a reference, you have absolutely no need to worry that the pointer will be copied or blurred by the owner or something like that.


Regarding the use of auto_ptr, in fact, we just need to use the Auto keyword in the code to do type inference, then we actually rewrite our own code to use UNQIUE_PTR, we do not need to change more user code.


The unique_ptr of c++11

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.