【问题标题】:C++ Reference IssueC++ 参考问题
【发布时间】:2014-09-01 02:46:00
【问题描述】:

我最近问了一个关于在 C++11 中创建类的正确方法的问题。我通过建立一个Tree 类来练习,我收到了一些很棒的建议。但是,我在理解为什么我的代码不起作用时遇到了一些麻烦。

尤其是,我无法理解为什么我的 insert 方法无法正常工作。

template<typename T>
class Tree {
private:
  struct Node {
    T data;
    Node* p_left;
    Node* p_right;
  };

  Node* newNode(T data) { return new Node {data, nullptr, nullptr}; }

  Node* root_;

  //Other functions, etc... (copy constructor and copy assignment operator)

public:
  void insert(T const data) {
    Node*& root = root_;
    while (root != nullptr) {
      root = (data <= root->data ? root->p_left : root->p_right);
    }
    root = newNode(data);
  }

  Tree(): root_(nullptr) {}

  //Other constructors, functions, etc...
};

如果我创建一个新的Tree 对象,然后用一些数据填充该对象,则该对象仅保留最后插入的数据。我知道我在某个地方因为我的指针引用而搞砸了,但我不知道在哪里。任何正确方向的提示将不胜感激。

【问题讨论】:

  • 你知道如何使用调试器来单步调试你的代码吗?
  • 您希望插入方法如何工作?什么是正确的函数?
  • @Fumu7 你的意思是我期望它做什么?它检查树中的空白区域,如果没有空白区域,则将数据适当地插入树中,以便创建 BST

标签: c++ class pointers reference


【解决方案1】:

两个问题...首先,在第一次插入树时,您没有更新 root

if (root == nullptr) { return newNode(data); }

事实上,您正在返回新节点,即使 insert 函数返回 void。如果您完全删除该行,代码应该可以工作。如果rootnullptr 开头,则将跳过while 循环并将root 更新为新节点。

第二个问题是您使用的是对节点指针的引用,这意味着您每次创建新节点时都会移动 Tree 的 root_。这不一定是个好主意。就个人而言,我会这样写:

void insert(T const data) {
    Node** proot = &root_;
    while (*proot != nullptr) {
        proot = (data <= (*proot)->data ? (*proot)->p_left : (*proot)->p_right);
    }
    *proot = newNode(data);
}

【讨论】:

  • 他不应该把它分配给root_吗?
  • 我认为这就是他试图让root 成为Node*&amp;root_ 的目的。但是,导致了另一个问题,因为无法重定向引用。
  • @Idgabbay 谢谢!是的,整个return newNode(data) 行是一个错字。抱歉,您的无知是什么意思“每次[我]创建一个新节点时移动[我的]树的root_?”我理解你的代码,我只是觉得双指针在 C++ 中某种程度上是一件坏事,并且在需要时应该将所有内容都写为对指针的引用。显然这是不正确的,因为我的代码不起作用。
  • 当然可以。在insert 的原始实现中,您已将root 设置为对root_ 的引用。在 C++ 中,一旦创建了引用,它就只能引用它。实际上,root 在那时只是root_ 的别名。在您的 while 循环中,您尝试沿着树向下走,但不是将临时指针向下移动,而是在每一步重新分配 root,因此 root_。一旦你从树上走了一步,你就移动了你的树的root,把你的树的根和它另一边的所有东西都扔掉了。
  • @Idgabbay 另外,我想你的意思是Node** proot = &amp;root_;
猜你喜欢
  • 1970-01-01
  • 2018-05-13
  • 2011-01-18
  • 1970-01-01
  • 2012-09-14
  • 1970-01-01
  • 2014-10-03
  • 2011-01-20
  • 1970-01-01
相关资源
最近更新 更多