【发布时间】:2021-12-27 11:36:53
【问题描述】:
我正在尝试使用智能指针实现二叉搜索树,并且我已经阅读了实现它的推荐方法是使用 unique_ptr,因为父母拥有孩子,并且二叉搜索树中没有多个所有者。
以这棵树为例,
10
4 20
2 5 11 30
3
这里 4 是 10 的左孩子,2 是 4 的左孩子,3 是 2 的右孩子,依此类推。
现在结构看起来像,
template<typename T>
struct TreeNode {
T data;
std::unique_ptr<TreeNode<T>> left, right;
};
有一个unique_ptr<TreeNode<T>> root 指向根。
现在,如果我理解正确,unique_ptr's 不能被复制或分配,并且他们拥有该对象的唯一所有权。
因此,如果我想遍历树,我无法执行诸如将 std::unique_ptr<TreeNode<T>> temp 初始化为根并从那里遍历每个节点的操作,因为一旦我尝试设置 root 即会抛出错误unique_ptr 到 temp。
那么我需要使用TreeNode* 类型的原始指针来遍历树并执行操作吗?这样做是好的还是安全的?对于我在这棵树上的所有操作,我是否必须使用原始指针?
另一个问题是删除节点。如果我说要删除值为3 的节点。如果我初始化TreeNode* temp 类型的原始指针并到达Treenode 3。那么如果我调用 delete(temp) 会发生什么?来自TreeNode 2 的unique_ptr 指向TreeNode 3。这个指针会发生什么?
【问题讨论】:
-
如果我打电话给
delete(temp)会发生什么 - 未定义的行为。 -
TreeNode*可用于遍历树(只要您不将该指针用于其所有者(转移或删除))。 -
@Evg 仅当持有它的
unique_ptr被访问或销毁时 -
使用原始指针没有错,智能指针负责所有权,如果您只使用智能指针作为所有权,那么在您的代码中很清楚任何原始指针都不拥有指向的对象
-
"如果我说要删除节点" 您应该只需要像
left = nullptr;、root = nullptr;这样的代码来删除节点(及其子节点)。没有delete可写。root = std::move(root->left);之类的代码也可能有用。
标签: c++ pointers binary-search-tree smart-pointers unique-ptr