没有()打破了std :: unique_ptr背后的想法吗?

时间:2014-08-18 19:27:17

标签: c++ c++11 smart-pointers

示例代码:

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

}

这不会打败std::unique_ptr背后的整个目的吗?为什么允许这样做?

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

4 个答案:

答案 0 :(得分:13)

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

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

  

通过*或&amp;独立于调用者的方式接受窗口小部件   管理它的一生。大多数时候,我们不想承诺   参数类型中的生命周期策略,例如要求对象为   由特定的智能指针持有,因为这通常是不必要的   限制性的。

当函数是接收器时,我们应该通过unique_ptr

  

只能通过移动对象来传递unique_ptr by value   以及从呼叫者到被呼叫者的独特所有权。任何功能   像(c)取得对象的所有权远离来电者,和   要么将其摧毁,要么将其向前移动到其他地方。

最后通过引用传递unique_ptr,我们可能会修改它以引用不同的对象:

  

这应该只用于接受输入/输出unique_ptr,当   函数应该实际接受现有的unique_ptr和   可能会修改它以引用不同的对象。这是一个糟糕的方式   只接受一个小部件,因为它仅限于特定的   来电者的终身策略。

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

在您的具体示例中:

int* myPtr = intPtr.get();

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

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

答案 1 :(得分:7)

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

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

答案 2 :(得分:5)

您展示的示例并没有违背std::unique_ptr的目的,即维护内存分配和释放的所有权。第std::unique_ptr<int> intPtr{new int(3)}行分配了一个新的int并获得了它的所有权。

*myPtr = 4不会更改该所有权,只需通过int检索到的指针为std::unique_ptr::get() 的内容指定值。 std::unique_ptr仍然拥有int的已分配内存。

答案 3 :(得分:3)

Get只允许您获取原始指针。否则,当您拥有unique_ptr时,您将无法使用基于指针的API,因为唯一的选择是release,这会使唯一指针无效。所以你得到get,它允许使用基于指针的API,而不必强迫每个人都使用unique_ptr。如果没有get,则只能调用 - &gt;和*在指针上,但如果你有一个原始类型,那将首先失去unique_ptr