Объединение & & операторов

Я читал реализацию List (и его node) с использованием классов, и я нашел пару вещей, которые я не совсем понимаю. Вот код в классе Node, который я не понимаю:

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

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

Что такое * & в точку? Я не понимаю, какая переменная возвращается этим методом.

Я думаю, что получаю это сейчас, позже у меня есть эти строки (внутри класса List):

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

Означает ли это, что я сохраняю следующий адрес в node *?

Примечание. На второй вопрос ответили в комментариях. Спасибо за ответы.

Ответ 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;

не будет modify n.next - и в этом случае он останется неинициализированным, потому что getNext возвращает rvalue здесь.

Альтернативно, возвращаясь по ссылке:

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

изменит n.next, так как x является ссылкой на n.next.

Ответ 2

Node*& getNext();

Возвращает ссылку на Node*. Почему они решили вернуть неконстантную ссылку на указатель, который позволяет изменять его значение вызывающими функциями... Я не знаю.

Ответ 3

Это означает, что вы возвращаете указатель по ссылке. Если кто-то может изменить фактический указатель внутри node:

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;
};

Эти фрагменты кода почти одинаковы, но последний

  • короче,

  • проще, а

  • позволяет обращаться к указателю next также к объекту const.

Итак, учитывая всю эту ненужную сложность и ограничение, не говоря уже о Java-измах, таких как префикс Get и использование this->, вы можете смело предположить, что конструкции и даже имена, которые вы видите в этом коде, скорее всего, не имеют смысла и даже с отрицательным эффектом; поскольку, конечно, метод GetNext имеет ограничение доступа.

Техническая информация: & означает, что С++ говорит "ссылка", а самое основное объяснение ссылки на С++ - это псевдоним для некоторого объекта. В С++ 03 ссылка была неотличима от объекта, на который она ссылалась. Независимо от версии С++ в действительном коде нет такой вещи, как нулевая ссылка.

Чтобы действительно узнать о указателях и ссылках, вы должны использовать хороший учебник С++, а не полагаться на ответы в сетевых форумах.

В списке SO С++ FAQ есть много хороших предложений для учебников.