【问题标题】:Binary tree pointer to the root needs to be referenced and dereferenced. Why?需要引用和取消引用指向根的二叉树指针。为什么?
【发布时间】:2014-07-28 07:53:40
【问题描述】:

我的问题是为什么我需要取消引用和引用指针才能使以下代码工作? ref/deref 不会互相取消吗? 如果有人能像我五岁一样解释它,我将不胜感激:)

代码:

template <typename T> 
class binNode {
private:
    T key;
public:
    binNode * left;
    binNode * right;
    binNode * parent;
    binNode() {
        this->left = NULL;
        this->right = NULL;
        this->parent = NULL;
    }
    // arg constructor:
    binNode (T key) {
        this->key = key;
        this->left = NULL;
        this->right = NULL;
        this->parent = NULL;
    }

    T getKey() {
        return this->key;
    }
    void setKey(T key) {
        this->key = key;
    }
};

template<typename T> class Tree {
private:
    binNode <T> *root;
public:
    Tree() {
        this->root = NULL;
    }
    Tree(binNode <T> * node) {
        node->parent = NULL;
        this->root = node;
    }
    /* THIS IS THE PART I  DON'T GET */
    void addNode(binNode<T> *&x, binNode<T> * node) { // what's up with the *&???
        if (x == NULL) {
            x = node;
            return;
        } else if (x->getKey() == node->getKey()) {
            node->left = x;
            node->parent = x->parent;
            x->parent = node;
            return;
        }

        if (node->getKey() < x->getKey()) {
            addNode(x->left, node);
        } else {
            addNode(x->right, node);
        }

    }

    void addNode(binNode<T> * node) {
        addNode(this->root, node);
    }

    binNode<T> * treeSearch(binNode<T> * x, T key) {
        if (x == NULL || key == x->getKey()) {
            return x;
        }
        if (key < x->getKey()) {
            return treeSearch(x->left, key);
        } else {
            return treeSearch(x->right, key);
        }
    }

    void printOrdered() {
        inorderTreeWalk(root);
        cout << endl;
    }

    void inorderTreeWalk(binNode<T> * node) {
        if (node != NULL) {
            inorderTreeWalk(node->left);
            cout << node->getKey() << '\t';
            inorderTreeWalk(node->right);
        }
    }

};

这里是主要功能(#inlude不包括在内)

int main() {
    Tree<int> T (new binNode<int>(10));
    // Tree<int> T = new binNode<int>(10);

    T.addNode(new binNode<int> (11));
    T.addNode(new binNode<int> (9));
    T.addNode(new binNode<int> (8));
    T.addNode(new binNode<int> (12));

    T.printOrdered();

}

【问题讨论】:

  • 注意:您可能想了解 smart 指针,例如 std::unique_ptr(需要 C++11),因为我很确定您的代码会泄漏内存。
  • +1 给马修。如果 C++11 不可用,Boost smart pointers 提供替代方案。

标签: c++ pointers reference binary-tree dereference


【解决方案1】:

这不是指针的引用/解除引用,它是指针的引用。这是必要的,因为...

void addNode(binNode<T> *&x, binNode<T> * node) {
    if (x == NULL) {
        x = node; // ...here...
        return;
    } else // ...

...您正在分配参数x

如果您没有通过引用传递指针x,您将分配给参数的本地副本:

void addNode(binNode<T> * x, binNode<T> * node) {
    if (x == NULL) {
        x = node; // this acts on the local copy only, and thus does nothing.
        return;
    } else // ...

【讨论】:

  • 上帝...所有这些指针,指针的指针,指针的引用......我想是时候睡觉了!非常感谢!我想我现在理解得更好了:)
  • @RafazZ:你已经习惯了。一旦你这样做了,拥有他们是一个非常好的胜利。 (并且不要忘记&amp;&amp;,C++11 的“右值引用”。它允许为“源”对象是“右值”的情况提供特殊的复制构造函数和赋值运算符;即临时。他们在这种情况下允许更有效的“移动语义”,即将数据成员从临时对象移动到您的对象,而不是必须深度复制它们。)此外,设计良好的代码应该使用“裸”指针非常非常谨慎。这就是马蒂厄在评论中指出的。
【解决方案2】:

通过指针(没有引用),您可以获得地址的本地副本。这意味着您可以操纵会改变的指针(在本例中为 *x)后面的值。但是,如果您更改地址本身,则该地址的行为会像本地副本一样,并且在离开该方法后您会丢失地址更改。

【讨论】:

    猜你喜欢
    • 2021-07-22
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多