Can't () break the idea of ​​std :: unique_ptr?

Code example:

#include<memory> #include<iostream> int main() { std::unique_ptr<int> intPtr{new int(3)}; int* myPtr = intPtr.get(); *myPtr = 4; std::cout<<"New result for intPtr: "<< *intPtr.get()<<std::endl; } 

Didn't that exceed all the goals for std::unique_ptr ? Why is this allowed?

Edit: I thought the whole purpose behind std :: unique_ptr was to have only ownership of the object. But in this example, the object can be modified using another pointer. Isn't that a defeat of the purpose of std :: unique_ptr?

+6
source share
4 answers

While Smart Pointers control the lifetime of the pointed object, it is often still useful to have access to a basic raw pointer.

In fact, if we read Herb Sutter GotW # 91 Solution: Smart Pointer parameters, he recommends passing parameters by pointer or reference, when the function is agnostic to the parameter lifetime, he says:

Skip * or or accept the widget no matter how the caller controlling his life expectancy. In most cases, we do not want a lifetime policy in the parameter type, for example, requiring the object to be stored in a specific smart pointer, because it is usually useless restrictive.

and we must pass unique_ptr when the function is a receiver:

The transfer of the unique_ptr value is only possible when moving the object and its unique property from the caller. Any function, for example, (c) obtains ownership of the object from the caller and either destroys it or moves it further to another location.

and finally pass unique_ptr by reference when we can change it to reference another object:

This should only be used to accept in / out unique_ptr when a function should actually accept an existing unique_ptr and potentially modify it to refer to another object. This is a bad way to simply accept a widget, as it is limited to a specific life strategy in the caller.

Of course, we need to get the main pointer if we need to interact with C libraries that accept pointers.

In your specific example:

 int* myPtr = intPtr.get(); 

There is no transfer of ownership to another smart pointer, so there is no problem if you are not trying to execute the delete pointer through myPtr . You can transfer ownership to another unique_ptr by moving it:

 std::unique_ptr<int> intPtr2( std::move( intPtr ) ) ; 
+12
source

This does not negate unique_ptr goals unique_ptr all. The type of smart pointer defines the semantics of ownership, but there may be times when you need to use a base object. For example, you have an object belonging to unique_ptr , but it needs to call a method that expects the object by reference. You can then dereference the .get() pointer to pass the reference object to the method.

What you should not do is to save the resulting index so that it acquires ownership. This is one of the cases when a language gives you tools to work correctly, and if you take a raw pointer and save a second property for it, then this is a problem with using the tool.

+7
source

Get only allows you to get a raw pointer. Otherwise, you cannot use the pointer API if you have unique_ptr , since release is the only alternative, which makes the unique pointer useless. This way you get get , which allows you to use pointer-based APIs, without forcing everyone to use unique_ptr . Without get you could only call the β†’ and * pointer, but if you have a primitive type, it could mean defeat with unique_ptr in the first place.

+3
source

The example you std::unique_ptr does not exceed the goal of std::unique_ptr , namely, to retain ownership of the allocation and freeing of memory . The string std::unique_ptr<int> intPtr{new int(3)} allocates a new int and takes responsibility.

The string *myPtr = 4 does not change the owner, just assigns a value to the contents of int using the pointer obtained with std::unique_ptr::get() . std::unique_ptr still owns allocated memory for int .

+3
source

Source: https://habr.com/ru/post/974001/


All Articles