50

Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
Are there benefits of passing by pointer over passing by reference in C++?

In both cases, I achieved the result. So when is one preferred over the other? What are the reasons we use one over the other?

#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
    int z = *x;
    *x=*y;
    *y=z;
}
void swap(int& x, int& y)
{
    int z = x;
    x=y;
    y=z;
}

int main()
{
    int a = 45;
    int b = 35;
    cout<<"Before Swap\n";
    cout<<"a="<<a<<" b="<<b<<"\n";

    swap(&a,&b);
    cout<<"After Swap with pass by pointer\n";
    cout<<"a="<<a<<" b="<<b<<"\n";

    swap(a,b);
    cout<<"After Swap with pass by reference\n";
    cout<<"a="<<a<<" b="<<b<<"\n";
}

Output

Before Swap
a=45 b=35
After Swap with pass by pointer
a=35 b=45

After Swap with pass by reference
a=45 b=35
Community
  • 1
  • 1
cppcoder
  • 22,227
  • 6
  • 56
  • 81

5 Answers5

29

A reference is semantically the following:

T& <=> *(T * const)

const T& <=> *(T const * const)

T&& <=> [no C equivalent] (C++11)

As with other answers, the following from the C++ FAQ is the one-line answer: references when possible, pointers when needed.

An advantage over pointers is that you need explicit casting in order to pass NULL. It's still possible, though. Of the compilers I've tested, none emit a warning for the following:

int* p() {
    return 0;
}
void x(int& y) {
  y = 1;
}
int main() {
   x(*p());
}
moshbear
  • 3,282
  • 1
  • 19
  • 33
  • 1
    References don't restrict the referring object to referring to something valid. You can return a reference to a local variable, for example. – Seth Carnegie Dec 20 '11 at 05:22
  • 1
    It is possible to get a an invalid reference if you dereference a NULL pointer, so you still need to be careful in the calling code. See http://stackoverflow.com/questions/57483/what-are-the-differences-between-pointer-variable-and-reference-variable-in-c/57656#57656 – Mark Ransom Dec 20 '11 at 05:22
  • 1
    It's possible, but unless you're dereferencing unchecked pointers, then it shouldn't happen. And if you don't check pointers before dereferencing them, then I have news for you... – moshbear Dec 20 '11 at 05:24
  • @moshbear, it was a lesson I had to learn the hard way. And it wasn't even my code! – Mark Ransom Dec 20 '11 at 05:32
  • I simplified my answer and gave an example of the infamous null reference. – moshbear Dec 20 '11 at 05:38
  • @moshbear, the more realistic scenario where you'd dereference a null pointer doesn't need a cast - `x(*GetIntPtr());` where `GetIntPtr()` returns `NULL`. See the link I posted earlier for a more thorough discussion. – Mark Ransom Dec 22 '11 at 05:15
  • @MarkRansom Fixed. Still, making assumptions on pointer values is always a bad thing. From NULLs to unaligned accesses, a multitude of subtle bugs can appear. – moshbear Dec 22 '11 at 07:57
  • With gcc 4.9.2 I get: a.cpp:8:8: error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int* (*)()’ – Ondřej Čertík Mar 04 '15 at 19:48
  • @OndřejČertík [edit: `*p` -> `*p()`] – moshbear Mar 06 '15 at 00:42
6

In fact, most compilers emit the same code for both functions calls, because references are generally implemented using pointers.

Following this logic, when an argument of (non-const) reference type is used in the function body, the generated code will just silently operate on the address of the argument and it will dereference it. In addition, when a call to such a function is encountered, the compiler will generate code that passes the address of the arguments instead of copying their value.

Basically, references and pointers are not very different from an implementation point of view, the main (and very important) difference is in the philosophy: a reference is the object itself, just with a different name.

References have a couple more advantages compared to pointers (e. g. they can't be NULL, so they are safer to use). Consequently, if you can use C++, then passing by reference is generally considered more elegant and it should be preferred. However, in C, there's no passing by reference, so if you want to write C code (or, horribile dictu, code that compiles with both a C and a C++ compiler, albeit that's not a good idea), you'll have to restrict yourself to using pointers.

4

Pass by pointer is the only way you could pass "by reference" in C, so you still see it used quite a bit.

The NULL pointer is a handy convention for saying a parameter is unused or not valid, so use a pointer in that case.

References can't be updated once they're set, so use a pointer if you ever need to reassign it.

Prefer a reference in every case where there isn't a good reason not to. Make it const if you can.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
4

Here is a good article on the matter - "Use references when you can, and pointers when you have to."

seaotternerd
  • 6,298
  • 2
  • 47
  • 58
rocky
  • 1,037
  • 1
  • 11
  • 19
2

Use references all the time and pointers only when you have to refer to NULL which reference cannot refer.

See this FAQ : http://www.parashift.com/c++-faq-lite/references.html#faq-8.6

Sanish
  • 1,699
  • 1
  • 12
  • 21