-1

So I have a piece of code here ,

somefunc(class* &head , int value);

I have a question , that what does * and & denote hear , aren't they the same thing ?? a pointer and reference both are addresses right ?

somefunc(class* head , int value);

it can be written like this also right ? ... the person I am learning from said that the above code will modify the linked list and the below one will not ... can anyone explain that to me!

  • 1
    Top code means reference of a pointer to something of type class. Below code means pointer to something of type class. – kiner_shah Dec 31 '21 at 08:05
  • `int i = 1; int* p = &i; int* &q = p;` Try to understand this. This is your first case. Now, if you modify `q`, since it's the reference of `p`, so `p` will be modified too. – Yves Dec 31 '21 at 08:12
  • Replace (in thoughts) class* with pclass. A pointer to class type. Then you get somefunc(pclass& head , int value) – Sebastian Dec 31 '21 at 08:25
  • `class* head = nullptr; somefunc(head, 0);` with the first function signature after the function call `head` may be non-null, but with the second signature it's guaranteed to still be null; the first signature allows you to overwrite the pointer the user passed to the function, but in the second case you're just working with a copy of the address. `somefunc(new class(), 1)` only compiles with the second signature... – fabian Dec 31 '21 at 09:04
  • I disagree about this specific duplicate (pointer vs ref) != (pointer vs ref to pointer) – Sebastian Dec 31 '21 at 09:09

2 Answers2

2

A challenge for beginners in C++s passing of parameters is that the calltype (by-reference vs. by-value) and the type of a parameter are easy to mix up.

A call to somefunc(SomeType* head, int value) transfers both parameters by-value. This means, the value is copied and the function uses the only the copy, not the original value. The parameters are named head and value and the types are SomeType* and int.

A call to somefunc(SomeType* &head, int &value) transfers both parameters by-reference. The value is not copied, instead a reference to the original values is created and this reference is used in the function. Changes made to either head or value are made via this reference to the original values. But the types of the parameters are still SomeType* and int.

Your example uses somefunc(SomeType* &head, int value). This means that head is passed by-reference and the original value can be changed in the function, whereas value is passed by-value. It's a mix of the two samples above.

It helps if you try to separate the type from the call-type and the name.

|----------------------|----------------------|
|SomeType*     &head   |   int   value        |
|----------------------|----------------------|
|^^type^^    ^by-ref^  | ^type^ ^by-value^    |
|----------------------|----------------------|

This becomes clear when you use a typedef/using declaration like this:

using SomeTypePtr = SomeType*;

someFunc(SomeTypePtr &head, int value)

Note: Technically speaking there is no such thing as a "by-reference calltype". A function will always use parameters "by-value" and the actual type of head is SomeType*&. It's just that the compiler creates a reference and passes it by-value. But what I described above is easier to understand.

Hajo Kirchhoff
  • 1,969
  • 8
  • 17
  • If you pass a pointer by value, you can access the underlying object and change it. That adds to the confusion. – Sebastian Dec 31 '21 at 08:41
  • Yes, but that is a different kind of confusion: pointer vs. pointee. You still cannot change the pointer, but of course you can use the pointer. References, pointers etc... can be confusing for someone starting out. – Hajo Kirchhoff Dec 31 '21 at 15:30
1
somefunc(class* &head , int value);

The parameter head is a reference to a pointer, and a non-const reference as well. The assumption here would be that somefunc is assigning an address to head in this circumstance, and returning it to you.

Non-const references can be very vague however. For instance, there's no way to know from the function's declaration itself if somefunc expects head to also act as an input too, or if it is only assigning to it. You may need to check the function's documentation to be sure, if the function or parameter's naming isn't clear.

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101