传递函数时的unique_ptr行为

时间:2015-08-02 08:16:08

标签: c++ smart-pointers unique-ptr auto-ptr

在下面的代码片段中,我在传递unique_ptr作为值时遇到分段错误。通常这是auto_ptr的已知问题,因为所有权问题(受让人指针变为NULL),在分配后无法访问它。 但是为什么我面对与unique_ptr相同的问题,即使它有移动语义。

我理解auto_ptr使用复制构造函数和unique_ptr使用移动函数来转移所有权。但是在这两种情况下,受让人指针变为空,那么在这里移动语义的意义是什么。我相信如果将unique_ptr作为类似下面的语句传递,编译器应该闪烁错误,因为复制构造函数在unique_ptr中是私有的。你能不能就这种行为对此有所了解。

@den_cubs.each do |dc|
  dc.each do |k,v|
    # now here you can display all attributes for the cubs
  end
end

以下是代码段:

unique_ptr<Test> a = p;//deleted function (copy constructor).

3 个答案:

答案 0 :(得分:3)

通过编写std::move(p),您将p投射到r值引用。 unique_ptr有一个构造函数,它接受一个r值引用(移动构造函数),因此它使用此移动构造函数构造by-value参数,并且没有编译错误。

除非您想转让所有权,否则不应按值unique_ptr传递值。

如果转移所有权,则外部作用域中的unique_ptr不再拥有任何内容,并且取消引用它是未定义的行为。

在这种情况下,您应该通过const引用传递Test

void fun(const Test& t) {
    std::cout << t.m_a << std::endl;
} 

int main(){
    auto p = std::make_unique<Test>(5);
    fun(*p);
}

有关如何传递智能指针的更多信息,请参阅here

答案 1 :(得分:1)

此处不涉及已删除的复制构造函数。 unique_ptr有一个使用的移动构造函数,因为您明确要求使用std::move从源移动。

你不应该使用移动的值,除非将其销毁分配给它。

这不是错误。编译器可能会发出警告,但由于您已明确移动它,因此可以合理地假设您知道自己在做什么。

答案 2 :(得分:0)

不使用unique_ptr作为值,而是将其作为引用传递。 您创建一个唯一的指针。然后使用移动构造函数从该构造另一个unique_ptr。所以原始设置为null。这就是移动unique_ptr时会发生什么。老实说,因为我没有机会使用auto_ptr,所以无法对此行为发表评论。

void Fun( const std::unique_ptr<Test>& p1 )
{
 cout<<p1->ma;
}