【发布时间】:2020-10-14 03:26:56
【问题描述】:
假设我有这个 BST 模板:
template <typename T> class Node {
private:
public:
T data;
Node *left;
Node *right;
Node(T dt) : data{dt}, left{nullptr}, right{nullptr} {}
~Node() {
this->data = 0;
this->left = nullptr;
this->right = nullptr;
}
};
template <typename T> class BST {
private:
Node<T> *_root;
_insert();
_add();
_printOrder_In(Node<T> *parent, std::ostream& os) {
if (!parent) return;
_printOrder_In(parent->left, os);
os << parent->data << ' ';
_printOrder_In(parent->right, os);
}
public:
BST() : _root{nullptr} {}
~BST();
insert();
add();
std::ostream& print(std::ostream& os = std::cout) {
_printOder_In(this->_root, os);
return os;
}
};
为什么下面的代码在我传递节点指针引用时有效,而当我传递节点指针时无效?
// BST MEMBER FUNCTIONS:
private:
void _insert(Node<T>* &parent, const T &val) { // works
//void _insert(Node<T>* parent, const T &val) { // doesn't work, apparently generates nodes indefinitely
if (!parent)
parent = new Node<T>{val};
else {
if (val < parent->data)
_insert(parent->left, val);
else if (val > parent->data)
_insert(parent->right, val);
else
return;
}
}
public:
void insert(const T &val) {
_insert(this->_root, val);
}
};
也与这种替代方法相反,它只使用传递的指针:
// BST MEMBER FUNCTIONS:
private:
void _add(Node<T>* parent, T val) {
if (parent->data > val) {
if (!parent->left) {
parent->left = new Node<T>{val};
} else {
_add(parent->left, val);
}
} else {
if (!parent->right) {
parent->right = new Node<T>{val};
} else {
_add(parent->right, val);
}
}
}
public:
void add(T val) {
if (this->_root) {
this->_add(this->_root, val);
} else {
this->_root = new Node<T>(val);
}
}
我了解指向点的引用将使我能够直接访问传递的指针。但是,我对这两种方法之间的区别感到困惑。在第二种方法中,尽管指针本身没有作为引用传递,但控制流中使用的本地副本仍然有效。
【问题讨论】:
-
//void _insert(Node<T>* parent, const T &val) {指针parent在您的函数中分配-它获取new Node的地址。如果您按值提供指针parent(如在排除行中),则此分配在离开函数后丢失。通过引用提供指针可确保分配“原始”指针(即您调用函数时使用的指针)并且更改变得持久。
标签: c++ pointers reference binary-search-tree