7

I was reading some code online and I found them passing node*& instead of just node* and I didn't really understand why.

My understanding was that you pass parameters by reference when you either want your changes to sort of propagate back to the original variable outside of the function (which a pointer would do) or if you wanted to avoid copying the object every time the function is called to avoid the copying overhead which is also what a pointer would do.

Am I wrong or are they? If I am, what am I getting wrong?

  • What about modifying passed in pointer? – Algirdas Preidžius Dec 07 '19 at 02:29
  • That allows you to modify the pointer itself, rather than just what the copy of the pointer points to with `node*`. – David C. Rankin Dec 07 '19 at 02:29
  • Oh. So if I am understanding this correctly, if I pass only `node*`, any changes I make are only made to the copy? If I pass `node* ptr` and do `ptr->leftChild = x`, wouldn't it affect the original pointer's leftChild pointer, outside the function call? Or would it remain unchanged unless I pass the pointer by reference? –  Dec 07 '19 at 02:32
  • @user362461 No. That's not how function arguments work (consider learning from a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)). What I meant was: modifying the argument itself: `void foo (node*& pn) {pn = new node;}` – Algirdas Preidžius Dec 07 '19 at 02:44
  • Yes I misunderstood your comment but I get it now. Yeah this makes perfect sense actually because a pointer is just another variable so it too will get copied. I feel kinda stupid hahaha, thanks a lot! –  Dec 07 '19 at 02:48
  • 2
    @user362461 When you pass `node*` the function receives a *copy-of-the-pointer* with its very own and very different address than the one in the caller ***but*** it still points to (holds as its value) the same address in memory as the original. So you can always modify what the pointer points to, but you cannot change the pointer itself if by passing a pointer. When you pass a reference, you are passing a *alias* to the original, so any changes made to the alias are made to the original as well. – David C. Rankin Dec 07 '19 at 02:57

2 Answers2

10

When you pass by reference, it acts as an alias -- be it a normal object or a pointer.

To explain in detail, let's consider below declaration:

int i = 10, *pi = &i;

Now following are the different meanings of passing and using them in various functions:

void foo_pointer (int* p) // 1st (can pass `&i` and `pi`)
{ 
  *p = 0;  // modifies `i`
   p = nullptr; // no effect on `pi`
}
void foo_pointer_reference (int*& p) // 2nd  (can pass `pi`)
{ 
  *p = 0;  // modifies `i`
   p = nullptr; // modifies `pi`
}
void foo_const_pointer_reference (const int*& p) // 3rd (can pass `pi`)
{ 
  *p = 0;  // ERROR
   p = nullptr; // modifies `pi`
}
void foo_const_pointer_const_reference (const int* const& p) // 4th (can pass `&i` and `pi`)
{ 
  *p = 0;  // ERROR
   p = nullptr; // ERROR
}

From above examples, you can see that another use case of declaring T*& as a function parameter is that, it restricts only pointer passing to that function. i.e. in above case &i is not allowed to be passed to 2nd and 3rd functions. However pi can be passed to all the functions.

iammilind
  • 68,093
  • 33
  • 169
  • 336
1

You can pass a pointer by reference if you want the function you call to change the pointer to point to something else. Other than that, I don't see any valid reason (but that is sometimes a valid reason).

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70