Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::unique_ptr::release()与std::move()的比较_C++_C++11 - Fatal编程技术网

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()
没有问题。它只会返回一个null
unique\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()};
}