C++ Returning Pointers/References
Tyler, that was very helpful explanation, I did some experiment using visual studio debugger to clarify this difference even further:-
int sample = 90;
int& alias = sample;
int* pointerToSample = &sample;
Name Address Type
&alias 0x0112fc1c {90} int *
&sample 0x0112fc1c {90} int *
pointerToSample 0x0112fc1c {90} int *
*pointerToSample 90 int
alias 90 int &
&pointerToSample 0x0112fc04 {0x0112fc1c {90}} int * *
Memory Layout
PointerToSample Sample/alias
_______________......____________________
0x0112fc1c | | 90 |
___________|___.....__|________|_______...
[0x0112fc04] ... [0x0112fc1c
In returnA() I'm asking to return a pointer; just to clarify this works because j is a pointer?
Yes, int *j = &a
initializes j
to point to a
. Then you return the value of j
, that is the address of a
.
In returnB() I'm asking to return a pointer; since a pointer points to an address, the reason why returnB() works is because I'm returning &b?
Yes. Here the same thing happens as above, just in a single step. &b
gives the address of b
.
In returnC() I'm asking for an address of int to be returned. When I return c is the & operator automatically appended?
No, it is a reference to an int which is returned. A reference is not an address the same way as a pointer is - it is just an alternative name for a variable. Therefore you don't need to apply the &
operator to get a reference of a variable.
In returnC2() I'm asking again for an address of int to be returned. Does *d work because pointers point to an address?
Again, it is a reference to an int which is returned. *d
refers to the original variable c
(whatever that may be), pointed to by c
. And this can implicitly be turned into a reference, just as in returnC
.
Pointers do not in general point to an address (although they can - e.g. int**
is a pointer to pointer to int). Pointers are an address of something. When you declare the pointer like something*
, that something
is the thing your pointer points to. So in my above example, int**
declares a pointer to an int*
, which happens to be a pointer itself.
Although Peter answered your question, one thing that's clearly confusing you is the symbols *
and &
. The tough part about getting your head around these is that they both have two different meanings that have to do with indirection (even excluding the third meanings of *
for multiplication and &
for bitwise-and).
*
, when used as part of a type indicates that the type is a pointer:int
is a type, soint*
is a pointer-to-int type, andint**
is a pointer-to-pointer-to-int type.&
when used as part of a type indicates that the type is a reference.int
is a type, soint&
is a reference-to-int (there is no such thing as reference-to-reference). References and pointers are used for similar things, but they are quite different and not interchangable. A reference is best thought of as an alias, or alternate name, for an existing variable. Ifx
is anint
, then you can simply assignint& y = x
to create a new namey
forx
. Afterwords,x
andy
can be used interchangeably to refer to the same integer. The two main implications of this are that references cannot be NULL (since there must be an original variable to reference), and that you don't need to use any special operator to get at the original value (because it's just an alternate name, not a pointer). References can also not be reassigned.*
when used as a unary operator performs an operation called dereference (which has nothing to do with reference types!). This operation is only meaningful on pointers. When you dereference a pointer, you get back what it points to. So, ifp
is a pointer-to-int,*p
is theint
being pointed to.&
when used as a unary operator performs an operation called address-of. That's pretty self-explanatory; ifx
is a variable, then&x
is the address ofx
. The address of a variable can be assigned to a pointer to the type of that variable. So, ifx
is anint
, then&x
can be assigned to a pointer of typeint*
, and that pointer will point tox
. E.g. if you assignint* p = &x
, then*p
can be used to retrieve the value ofx
.
So remember, the type suffix &
is for references, and has nothing to do with the unary operatory &
, which has to do with getting addresses for use with pointers. The two uses are completely unrelated. And *
as a type suffix declares a pointer, while *
as a unary operator performs an action on pointers.