std :: unique_ptr :: release()vs std :: move()

时间:2016-03-16 08:39:03

标签: c++ c++11

我有一个表示运行时上下文并构建树的类,树根保存在unique_ptr中。在构建树时,我想要提取树。这是它的外观(不可运行,这不是一个调试问题):

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::move()Context实例中提取根节点。

然而,有使用std::move()的替代方法,例如:

std::unique_ptr<Node> extractTree() {
    // This seems less intuitive to me
    return std::unique_ptr<Node>{this->root.release()};
}

std::move()是最佳选择吗?

2 个答案:

答案 0 :(得分:6)

你绝对应该使用第一个版本,因为第二个版本基本上完成了第一个版本所做的所有事情,代码更多,可读性更低。

从哲学上讲,第二个版本移动唯一指针,不多也不少。那么为什么要绕过桌子而不是使用现有的,更具可读性和更具惯用性的std::unique_ptr(std::unique_ptr&&)

最后,如果您将来某处的智能指针将包含自定义删除器,则第一个版本将确保删除器移动,第二个版本不会移动删除器。我可以想象一个程序员使用release从自定义删除unique_pointer构建非自定义删除器唯一指针。使用移动语义,程序将无法编译。

答案 1 :(得分:3)

你正在做的事情很危险。一旦调用getTree(),就不能再次调用它,这在界面上并不清楚。您可能想重新考虑您的设计(例如,shared_ptr可能会做得更好,或者只是将根存储为原始指针并手动处理释放)。

无论如何,如果你想坚持你的设计,使用std::move是两者中更好的选择,因为它会使你的意图更清晰。

编辑:显然'绝不'具有英语禁忌的特殊含义我不知道。可以根据需要调用函数两次或多次,但如果连续完成,则不会返回指向有效对象的指针。