What is the difference? Because this:
int Value = 50;
int *pValue = &Value;
*pValue = 88;
and ref version do the same:
I agree with justin's answer and would like to clarify it with the tiniest example.
Suppose you don't quite remember the syntax of a 2D image geometric library: is it
bool BooleanOr( const Bitmap & input1, const Bitmap & input2, Bitmap * output );
or is it
bool BooleanOr( Bitmap * output, const Bitmap & input1, const Bitmap & input2 );
If in your company everybody uses pointers for outputs and const references for inputs it's virtually impossible to make a mistake: when you see calls such as
BooleanOr( thisBitmap, thatBitmap, & anotherBitmap );
you immediately know the syntax.
In this case, they are equivalent.
It does not matter which you use, and neither is "best".
If you really want to choose between them then the reference is probably more idiomatic. I generally stick to references wherever I can because my OCD likes it: they feel "tighter", cannot be re-bound (with or without you noticing) and don't require a dereference to get to the value.
But I'm not aware of any general consensus on the issue for cases such as this.
Also note that the two may not compile to the same code if your implementation does not implement references with pointers, though I know of no implementation like that, and you wouldn't notice the difference anyway.
The differences are:
Reference is an alias of an object and has the same address as the object.
int a; // address of a : 0x0012AB
int &ref = a; // address of ref : 0x0012AB (the same)
References must be initialized :
int &ref = a; // GOOD, is compiling
int &ref; // BAd, is not compiling
Pointer is another variable that holds an address:
int a = 5; // address of a : 0x0012AB
int *p = &a; // address of p : 0x0012AF (is different )
// value of a is 5
// value of p is 0x0012AB (address of a)
Pointers can be NULL
int *p = NULL;
A pointer is the address of the memory location. You can change the value of that address to point at different memory addresses.
A reference is an alias of the variable. You can only assign this alias during declaration. You cannot change which variable the reference is an alias of after it's declared.
The following pointer assignments are not possible with references.
int a = 10;
int b = 20;
int* pInt = NULL; // A pointer pointing at nothing.
pInt = &a; // pInt now points at a
pInt = &b; // pInt now points at b
As for which one is better, it all depends on context.
I use references for method and function parameters.
void updateFoo(Foo& foo)
I use references to alias complex objects.
Foo& foo = bar.getBaz().getFoo(); // easy access to foo
I use pointers for dynamically allocated objects.
Foo* pFoo = new Foo();
I use pointers for things which may point at different values (including no value at all).
Foo* pFoo = NULL;
if (condition1)
pFoo = &foo1;
else (condition2)
pFoo = &foo2;
As a general rule, I default to references and use pointers in places where the limitations on references cause problems.
Great answers here. I would like to point out 2 specific usages of references:-
Case 1: While implementing operator[]
. This operator typically needs to return something that can be used as the target of an assignment Example:-
vector<int> v(20);
v[1] = 5; //The target of the assignment is the return value of operator []
Here the operator []
returns a reference of the element at the specified index in the vector
. Had operator []
been designed to return a pointer to the element at the specified index the 2nd line would have to be written like this:-
*v[1] = 5
Now that makes v
look like it's a vector of pointers - which it's definitely not!! Thus for sanity to prevail - the operator []
returns a reference and not a pointer to the indexed element in the vector
Case 2: No explicit null
check required for references. Some answers have already talked about it - wanted to present the advantage using a code snippet:-
void fun(const int& val)
{
cout << val;
}
void fun(const int* val)
{
if (val){ //Additional overhead with pointers
cout << *val;
}
}
My rule of thumb is to favor using a reference or const reference, unless a pointer is required.
The reference may not be reseated, and it is syntactically cleaner. The reference also guarantees to you that the reference is not NULL
.
I may also use a pointer for convenience when using arrays.