get()是否打破了std :: unique_ptr背后的想法?

wiz*_*urd 11 c++ smart-pointers c++11

示例代码:

#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;

}
Run Code Online (Sandbox Code Playgroud)

这不是打败了背后的全部目的std::unique_ptr吗?为什么允许这样做?

编辑:我认为std :: unique_ptr背后的全部目的是拥有一个对象的唯一所有权.但是这个例子,可以通过另一个指针修改对象.这不是打败std :: unique_ptr的目的吗?

Sha*_*our 14

虽然智能指针管理指向的对象的生命周期,但访问底层原始指针通常仍然很有用.

事实上,如果我们阅读Herb Sutter的GotW#91解决方案:智能指针参数,他建议当函数与参数的生命周期无关时,通过指针或引用传递参数,他说:

通过*或&来接受一个小部件,与呼叫者管理其生命周期的方式无关.大多数情况下,我们不希望在参数类型中提交生命周期策略,例如要求对象由特定的智能指针保持,因为这通常是不必要的限制.

当函数是接收时,我们应该通过unique_ptr传递:

通过将对象及其唯一所有权从调用者移动到被调用者,只能通过值传递unique_ptr.任何像(c)这样的函数都将对象的所有权从调用者手中夺走,并将其销毁或者将其向前移动到其他地方.

unique_ptr当我们可以修改它以引用不同的对象时,最后传递一个引用:

当函数实际上接受现有的unique_ptr并且可能修改它以引用不同的对象时,这应仅用于接受输入/输出unique_ptr.这是一种接受小部件的坏方法,因为它仅限于调用者中的特定生命周期策略.

当然,如果我们必须与带有指针的C库接口,我们需要获取底层指针.

在您的具体示例中:

int* myPtr = intPtr.get();
Run Code Online (Sandbox Code Playgroud)

没有所有权转移到另一个智能指针,所以只要你不尝试delete通过指针就没有问题myPtr.您可以unique_ptr通过移动来将所有权转移到另一个:

std::unique_ptr<int> intPtr2( std::move( intPtr ) ) ;
Run Code Online (Sandbox Code Playgroud)


Mar*_*k B 7

这根本没有打败目的unique_ptr.智能指针的类型决定了所有权语义,但可能存在需要使用底层对象的情况.例如,您拥有一个由a拥有的对象,unique_ptr但需要通过引用调用期望该对象的方法.然后,您可以取消引用.get()指针以获取要传递给方法的引用对象.

不应该做的是以获得所有权的方式存储获得的指针.这是语言为您提供正常工作的工具之一,如果您使用原始指针并存储第二个所有权,那么使用该工具就会出现问题.

  • 给出的例子并不是很好,因为你应该为这种情况做[`*ptr`](http://en.cppreference.com/w/cpp/memory/unique_ptr/operator*). (3认同)

Rem*_*eau 5

您显示的示例并没有违反目的std::unique_ptr,即维护内存分配和释放的所有权。该行std::unique_ptr<int> intPtr{new int(3)}分配一个新的int并取得其所有权。

该行*myPtr = 4不会更改该所有权,它只是通过通过检索的指针为的内容分配一个值intstd::unique_ptr::get()。在std::unique_ptr仍拥有对所分配的内存int