【问题标题】:Combining & and * operators结合 & 和 * 运算符
【发布时间】:2012-10-13 17:27:07
【问题描述】:

我一直在阅读使用类的 List(及其节点)的实现,并且发现了一些我不太了解的东西。 这是Node类中我看不懂的代码:

    class Node {
      private:
         Data data;
         Node* next;
      public:
         Node*& getNext();
    };

    Node*& Node::getNext()
    {
       return this->next;
    }

*& 到底是什么?我不知道该方法返回了什么样的变量。

我想我现在明白了,稍后我有这些行(在类 List 内):

Node** node = &first;
node = &(*node)->getNext();       

这是否意味着我将 next 的地址存储在 node* 中?

注意:第二个问题已在 cmets 中回答。感谢您的回复。

【问题讨论】:

  • 这是对指针的引用。
  • 当您认为返回引用可能是一个好主意时,您应该始终提出两个问题:1) 返回的东西实际上是否归Node 的用户所有? 2) 引用永远不会比它所引用的对象寿命长吗?通常只在两个答案都是肯定的情况下才考虑返回参考。

标签: c++ class reference linked-list operators


【解决方案1】:

这是对指针的引用。这意味着函数返回的Node*Node::next的别名。

例如,假设您有:

Node n;
n.getNext() = NULL;

这会将n.next 设置为NULL

如果方法没有通过引用返回

Node* Node::getNext()  //no reference
{
   return this->next;
}

相同的代码

Node n;
n.getNext() = NULL;

不会修改n.next - 在这种情况下,它将保持未初始化 编译,因为getNext 在此处返回rvalue

或者,通过引用返回:

Node*& x = n.getNext();
x = new Node;

将修改n.next,因为x 是对n.next 的引用。

【讨论】:

  • -1 n.getNext() = NULL; for Node* Node::getNext() 不会编译。你不能分配给一个右值。
  • 我想我现在明白了。稍后(在类列表中)我有这些行 Node** node = &firstnode = &(*node)->getNext(); 这是否意味着我将下一个地址存储在节点 * 中?
【解决方案2】:
Node*& getNext();

返回对Node* 的引用。为什么他们选择返回对指针的非常量引用,这允许函数的调用者更改其值...我不知道。

【讨论】:

    【解决方案3】:

    这意味着您通过引用返回一个指针。这意味着有人可以修改节点内的实际指针:

    Node anode = /* something... */;
    anode.getNext() = nullptr;
    assert(anode.getNext() == nullptr); // assertion passed!
    

    这看起来不像你会使用它的情况。只需返回指针:

    Node* Node::getNext()
    {
       return next;
    }
    

    【讨论】:

      【解决方案4】:

      比较

      class Node {
        private:
           Data data;
           Node* next;
        public:
           Node*& getNext();
      };
      
      Node*& Node::getNext()
      {
         return this->next;
      }
      

      class Node {
        private:
           Data data;
        public:
           Node* next;
      };
      

      这些代码sn-ps实现几乎一样,但后者是

      • 更短,

      • 更简单,而且

      • 还允许访问 next 指针上的 const 对象。

      因此,考虑到所有不必要的复杂性和限制,更不用说诸如 Get 前缀和使用 this-> 之类的 Java 主义,您可以放心地假设您在该代码中看到的结构甚至命名, 很可能没有意义,甚至会产生不利影响——正如GetNext 方法所具有的那样,限制了访问。

      技术细节:& 是 C++ 的“引用”,而 C++ 引用的最基本解释是它是某个对象的别名。在 C++03 中,引用与它所引用的对象无法区分。无论 C++ 版本如何,有效代码中都不存在空引用。

      要真正了解指针和引用,您应该使用一本好的C++ 教科书,而不是依赖网络论坛中的答案。

      SO C++ FAQ book list 对教科书有很多好的建议。

      【讨论】:

      • 我本来打算投反对票,但后来我意识到通过引用返回也会破坏封装,所以 +1。
      猜你喜欢
      • 1970-01-01
      • 2020-12-17
      • 2020-05-28
      • 1970-01-01
      • 1970-01-01
      • 2014-09-30
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多