A reference is the variable/object it refers to - if int &b = a;, then b and a are the same variable and thus refer to the same object. An implementation might use a pointer, but that's not guaranteed or required. For all you know it could use some other magic wizardry.
Another thing about references is that they are great candidates for optimization, where are pointers are poorer candidates.
What threw me off was the returning the address. I was expecting it to return a pointer and the &(*(pVec)[i]); just confused me.
Correct me if I'm wrong:
When & is used on a variable name without a data type in front of it it is the address of operator. & after a data type makes it a reference to that data type. Isn't it also a bit shift operator for AND? Versatile little symbol the ampersand sign is :).
You're mostly correct, yes. It gets messy when you get into more complex declarations.
But yeah... in a declaration it indicates a reference.
In an expression, when used as a unary operator, it's the address-of operator
In an expression, when used as a binary operator, it's the bitwise AND operator
Oh. I thought it was just a compiler optimization technique to switch out the object with the reference, and references were simply pointers. I guess I learned something today.
No, the way functions work is if you don't pass in the variable by reference or else the function is just making a copy of the variable to manipulate. If you could return it by reference with a switch technique like that, I don't know what kind of errors you would run into for that.
Conceptually, a pointer is a variable which contains the address of another variable/object.
While conceptually, a reference is an "alternative name" for another variable/object.
IE:
1 2 3 4 5 6 7 8 9
int foo;
int* ptr = &foo;
// 'ptr' and 'foo' are different variables.
// one is an int, and one is a pointer
int& ref = foo;
// whereas 'ref' and 'foo' are just different names for the same variable.
In reality... references are often implemented as pointers because they're so similar. The differences between them are really only in concept and in syntax.
Sometimes you can return a reference to a temporary without realizing it. See if you can tell me which of these functions invokes undefined behavior when the result is used or assigned to:
1 2 3 4 5 6 7 8 9 10
int &f()
{
int v = 0;
return v;
}
int &g()
{
staticint v = 0;
return v;
}
The differences between them are really only in concept and in syntax.
There is a few differences but not many. One major one is that pointers can be null where as references must always hold a value (Well technically you could assign a null pointer to the reference but that is just hackish and you should be shot in the foot if you do that ;p).
1 2 3 4 5 6 7 8
// Ok
int* ptr = null;
// Not ok can't be null
int& ref = null;
// Not ok you must initialize the reference.
int& ref;
Another difference is that pointers can change what they point to where as references can only refer to one object.
1 2 3 4 5 6 7 8 9 10 11 12 13
// Ok changes what the pointer points to.
int one = 5;
int* ptr = &one;
int two = 2;
ptr = &two;
// Not ok. Doesn't change what the reference is referring to instead it assigns it.
int one = 5;
int& ref = one;
int two = 2;
ref = two;
Them are basically the two major differences other then syntax. In my opinion if you know that you don't need to refer to more then one thing and that it will never be null use a reference. All other times use a pointer.
@LB: im guessing it would be g() because since its returning a reference to a static object. idk why that would cause undefined behavior, but i see nothing wrong with f() since you could use the same idea (minus initialization) as a getter
i see nothing wrong with f() since you could use the same idea (minus initialization) as a getter
f() is returning a reference to a local variable 'v'.
As soon as f exits, 'v' goes out of scope and dies, so the reference f returns is to a variable that no longer exists. It's a bad reference (same idea as a bad pointer). So accessing it would be undefined.
oh... mu mistake. i see that now. i dont know why i got that before. because since its static it static it stays in scope and can thus be accessed. could you provide an example of when this is useful?
Here... since theSingleton is static local, it is constructed the first time get() is called. This avoids the 'static initialization order fiasco' which comes up if it were a global object (or a static member).