我有一个表示运行时上下文并构建树的类,树根保存在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()
是最佳选择吗?
答案 0 :(得分:6)
你绝对应该使用第一个版本,因为第二个版本基本上完成了第一个版本所做的所有事情,代码更多,可读性更低。
从哲学上讲,第二个版本移动唯一指针,不多也不少。那么为什么要绕过桌子而不是使用现有的,更具可读性和更具惯用性的std::unique_ptr(std::unique_ptr&&)
?
最后,如果您将来某处的智能指针将包含自定义删除器,则第一个版本将确保删除器移动,第二个版本不会移动删除器。我可以想象一个程序员使用release
从自定义删除unique_pointer构建非自定义删除器唯一指针。使用移动语义,程序将无法编译。
答案 1 :(得分:3)
你正在做的事情很危险。一旦调用getTree()
,就不能再次调用它,这在界面上并不清楚。您可能想重新考虑您的设计(例如,shared_ptr可能会做得更好,或者只是将根存储为原始指针并手动处理释放)。
无论如何,如果你想坚持你的设计,使用std::move
是两者中更好的选择,因为它会使你的意图更清晰。