Вы передаете указатель по ссылке по той же причине, по которой вы передаете не указатель по ссылке: чтобы функция могла изменять свое значение.
Позвольте мне использовать более простой пример
#include <iostream>
void foo(int*& x) {
*x = 42; // change the value of the int x points to
x = nullptr; // change the value of x
}
Первая строка изменяет значение, на которое указывает x
(но не изменяет x
). Вторая строка изменяет саму x
.
int main() {
int y = 42;
int* y_ptr = &y;
foo(y_ptr);
if (y_ptr == &y) std::cout << "cannot happen";
}
Поскольку мы установили x = nullptr
, y_ptr
больше не будет указывать на y
после вызова.
Теперь, если мы изменим foo
, чтобы не брать ссылку, мы get:
#include <iostream>
void foo(int* x) {
*x = 42; // change the value of the int x points to
x = nullptr; // change the value of x
}
Снова первая строка изменяет int
, на который указывает x
. Однако теперь вторая строка влияет только на x
локально для функции.
int main() {
int y = 42;
int* y_ptr = &y;
foo(y_ptr);
if (y_ptr == nullptr) std::cout << "cannot happen";
}
Значение y_ptr
нельзя изменить, передав его foo
, поскольку оно передается по значению.
В вашем коде у вас есть
Node* deleteHead(Node* &head)
{
if (head)
{
Node* temp = head;
head = head->next;
delete temp;
}
return head;
}
И когда вы пишете head = deleteNode(head)
, происходят две вещи:
- функция изменяет
head
(потому что она передается по ссылке), указывая на head->next
. - функция также возвращает эту "новую" головку (указывающую на
head->next
), которая назначается на head
.
Таким образом, вы в основном назначаете head
дважды. Поскольку head
передается по ссылке, deleteNode
будет делать правильные вещи без использования возвращаемого значения:
deleteNode(head); // this already does modify head
... или наоборот: если вы возвращаете "новую" голову ( head->next
) из функции и присвойте ее head
, тогда не имеет значения, если вы передадите указатель по ссылке, потому что присвоение, выполненное внутри функции, имеет тот же эффект.
Ваш код похож на
int* bar(int*& x) {
x = nullptr;
return x;
}
и затем вызовите его через
int y = 42;
int* y_ptr = &y;
y_ptr = bar(y_ptr);
, где тот же эффект может быть достигнут без использования возвращенного значения bar(y_ptr)
. Или то же самое без указателей (потому что указатели здесь действительно не имеют значения):
int moo(int& x) {
x = 0;
return x;
}
int x = 42;
x = moo(x); // same as `moo(x)`
PS: вам не нужны оба (вернуть указатель и назначить его уже в функции), поэтому лучше заставить функцию возвращаться void
.