【问题标题】:Binary trees in C++ using referencesC++中使用引用的二叉树
【发布时间】:2010-10-01 22:13:29
【问题描述】:

我希望使用引用而不是使用指针来实现二叉树(这通常是您在互联网上的每本书和每个网站中都可以找到的)。我尝试了以下代码:

class tree_node {
private:
    tree_node& left;
    tree_node& right;
    data_type data;
public:
    void set_left(tree_node&);
    // ... other functions here
};

void tree_node::set_left(tree_node& new_left) {
    this.left = new_left;
}

我收到以下错误: 错误 C2582: 'operator =' 函数在 'tree_node' 中不可用。

我知道我可以使用指针轻松实现它,但我想保持我的解决方案优雅且没有指针。你能告诉我哪里出错了吗?

【问题讨论】:

  • 谁说“优雅”的意思是“没有指针”?如果它可以用指针轻松完成,为什么要避免它们?
  • 不。我认为使用引用会更好看。无论如何,我一直愚蠢地忽略了在初始化后无法修改引用的事实。非常感谢您的及时回复。 :)

标签: c++ reference tree binary-tree


【解决方案1】:

您不能更改引用所指的对象1;一旦你初始化一个引用,它总是引用它被初始化的对象。

你应该使用指针。为此使用指针没有任何问题(使用指针也很干净,因为父节点拥有它们的子节点,因此清理和销毁很容易!)

(1) 好吧,你可以显式调用对象的析构函数,然后在赋值运算符实现中使用placement new,但这只是一团糟!

【讨论】:

  • 使用 shared_ptr 之类的东西可以让实现更加简洁!
  • @monoceres:嗯,shared_ptr 可能不合适,因为它是一个(意味着一个节点应该有一个所有者——它的父节点)。但是scoped_ptr 会是一个不错的选择。
  • 再好老的std::auto_ptr... 不完美,不代表没用——只要你意识到其中的陷阱,那就是:)跨度>
【解决方案2】:

您不能分配给参考文献。您尝试做的事情无法完成......没有大量的弯曲......(你基本上会破坏一个节点并在每次想要修改它时创建一个新节点。)

所有其他人都使用指针是有充分理由的。

【讨论】:

    【解决方案3】:

    引用不仅仅是语法较短的指针。它们是它们所指的实际对象的另一个名称,即使用作赋值的 lhs 也是如此。

    int i = 3;
    int j = 4;
    int &ref = i;
    ref = j;
    std::cout << i << "\n"; // prints 4: i itself has been modified, 
                            // because semantically ref *is* i
    

    也就是说,ref = ji = j 具有相同的效果,或者与*ptr = j 相同的效果,如果您先完成了int *ptr = &amp;i;。这意味着,“将对象j 的内容复制到ref 所指的任何对象中”。

    对于ref 的整个生命周期,它将始终引用i。它不能引用任何其他 int,也就是说它不能“重新就位”。

    引用数据成员也是如此,只是它们的生命周期与自动变量不同。

    所以,当您编写 this.left = new_left 时, 的意思 是,“将对象 new_left 的内容复制到 this.left 所指的任何对象中”。哪个 (a) 不是您的意思,因为您希望重新安排 this.left,并且 (b) 即使这是您的意思,也是不可能的,因为 this.left 有参考成员,这些成员本身不能重新就位.

    是 (b) 导致您看到的编译器错误,尽管 (a) 是您应该为此使用指针的原因。

    【讨论】:

      【解决方案4】:

      C++ 中的引用与其他语言中的引用不同。一旦设置了引用,在构建时,它就不能更改为其他任何内容。

      【讨论】:

        【解决方案5】:

        我的建议是使用 boost 的 shared_ptr 类而不是引用。这将使您不必担心管理指针的释放。你可能也对Boost's graph library感兴趣。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-11
          • 2011-07-24
          • 1970-01-01
          • 2015-06-10
          相关资源
          最近更新 更多