C++ std::unique_ptr::release()与std::move()的比较
我有一个表示运行时上下文并构建树的类,树根保存在C++ std::unique_ptr::release()与std::move()的比较,c++,c++11,C++,C++11,我有一个表示运行时上下文并构建树的类,树根保存在unique\u ptr中。当构建树完成时,我想提取树。这是它的外观(不可运行,这不是调试问题): std::move()是最佳选择吗?你所做的是危险的。一旦调用了getTree(),就不能再调用它了,这在界面上是不清楚的。您可能需要重新考虑您的设计(例如,共享的\u ptr可能做得更好,或者只是将根存储为原始指针并手动处理释放) 无论如何,如果你想坚持你的设计,使用std::move是两种方法中更好的选择,因为这会让你的意图更加清晰 编辑:显然“
unique\u ptr
中。当构建树完成时,我想提取树。这是它的外观(不可运行,这不是调试问题):
std::move()
是最佳选择吗?你所做的是危险的。一旦调用了getTree()
,就不能再调用它了,这在界面上是不清楚的。您可能需要重新考虑您的设计(例如,共享的\u ptr可能做得更好,或者只是将根存储为原始指针并手动处理释放)
无论如何,如果你想坚持你的设计,使用std::move
是两种方法中更好的选择,因为这会让你的意图更加清晰
编辑:显然“不得”在我不知道的英语中有一个特殊的禁止含义。可以调用函数两次或任意多次,但如果连续调用,则不会返回指向有效对象的指针。您肯定应该使用第一个版本,因为第二个版本基本上完成了第一个版本的所有操作,代码更多,可读性更低 从哲学上讲,第二个版本移动了唯一的指针,没有更多,也没有更少。那么,为什么不使用已经存在的、更具可读性和更惯用的
std::unique_ptr(std::unique_ptr&&)
最后,如果您的智能指针在将来的某个地方将持有自定义删除器,那么第一个版本将确保删除器也会移动,第二个版本不会移动删除器。我完全可以想象程序员使用
release
从自定义deleter unique\u指针构建非自定义deleter unique指针。使用移动语义,程序将无法编译 第二次调用getTree()
没有问题。它只会返回一个nullunique\u ptr
。为什么不能调用getTree()
两次呢?一旦根被移动,它就会被设置为nullptr
,因此再次从它移动会得到一个nullptr
,这对于空对象来说似乎是一个非常合理的行为。从函数签名和名称来看,您通常会认为整个对象基本上变得不可用吗?我不会的。如果他想保持这种方式,并且行为是他想要的,一切都很好,但他可能没有意识到后果。我认为有理由期望get…()
调用具有const
行为。我认为,将函数重命名为类似于extractTree()
的名称将更清楚地传达这样一个事实,即上下文
在这次调用后将不再有树。@kamikaze:这就是为什么我发现从这样一个函数中得到一个唯一的\u ptr
。-)还要注意的是,我可以做getTree()->something()
,但我从来没有意识到我只是用鼠标点击了这棵树,想知道为什么第二次语句会出错。移动它后,需要从this->root调用reset
。你最好也读一下这个答案@neuront:不,你没有。移动src后包含nullptr,重置是没有意义的!如果您发现自己在一个唯一的ptr上调用release()
,这是一个警告,说明您的逻辑可能不健全。@RichardHodges,除非您必须将所有权传递给C API。
class Context {
private:
std::unique_ptr<Node> root{new Node{}};
public:
// imagine a constructor, attributes and methods to build a tree
std::unique_ptr<Node> extractTree() {
return std::move(this->root);
}
};
std::unique_ptr<Node> extractTree() {
// This seems less intuitive to me
return std::unique_ptr<Node>{this->root.release()};
}