aby*_*s.7 5 c++ rvalue-reference unique-ptr move-semantics c++11
using Ptr = std::unique_ptr<int>;
Ptr f(bool arg) {
std::list<Ptr> list;
Ptr ptr(new int(1));
list.push_back(std::move(ptr));
if (arg) {
Ptr&& obj1 = std::move(list.front());
// Here |obj1| and |list.front()| still point to the same location!
list.pop_front();
return std::move(obj1);
}
else {
Ptr obj2 = std::move(list.front());
list.pop_front();
return obj2;
}
};
Ptr&& ptr1 = f(true); // |ptr1| is empty.
Ptr&& ptr2 = f(false); // |ptr2| is fine.
Run Code Online (Sandbox Code Playgroud)
完整来源在这里。
我不明白-为什么obj1,并list.front()仍然指向相同的位置后,std::move()被称为?
里面有你参考std::unique_ptr的list。
Ptr&& obj1 = std::move(list.front());
// ^^ THIS
Run Code Online (Sandbox Code Playgroud)
所以当你这样做时
list.pop_front();
Run Code Online (Sandbox Code Playgroud)
中的唯一指针list被销毁,并且您留下了对已被销毁的某个对象的悬空引用,通过从函数返回该对象来非法使用该对象。
更新: std::move实际上并没有移动std::unique_ptr. 如果我们看看如何std::move定义,我们会发现它只返回所移动表达式的右值引用。当你测试它时,它会变得有趣:
Ptr&& obj1 = std::move(list.front());
assert(obj1.get() == list.front().get());
Run Code Online (Sandbox Code Playgroud)
不过,您的else子句看起来不错,您应该在其余代码中使用该模式。
Ptr obj2 = std::move(list.front());
list.pop_front(); // OK; destroys the moved-from unique_ptr
return obj2; // OK; obj2 points to something valid and is not a dangling reference
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2410 次 |
| 最近记录: |