在下面的代码片段中,我在传递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).
答案 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;
}