Dan Brenner
Dan Brenner

Reputation: 898

C++ - Understanding References and Memory Addresses

I have read some of the technical differences between references and memory addresses here, however I am trying to find a more abstract way to understand them. Consider the code:

char foo = 'a';
char& bar = foo;
char& bar2 = *(char*)(&foo);
cout << bar << endl;
cout << bar2 << endl;

The output in both cases is 'a'. Is it then correct to conclude from this that a reference (bar2) is simply a memory address (&foo) with an associated type (char)? Or does this explanation fall apart?

Upvotes: 2

Views: 1149

Answers (3)

R Sahu
R Sahu

Reputation: 206607

The most succinct definition of a reference in C++ is that:

It declares a named variable as a reference, that is, an alias to an already-existing object or function.

  1. Its value is the same as the object it is an alias of.
  2. Its address (obtained by the & operator) is the same as the address of the object it is an alias of.

Upvotes: 5

Kerrek SB
Kerrek SB

Reputation: 477040

Any time you have a value (i.e. an object that is the result of evaluating an expression) in C++, you can bind that value to a reference variable. Evaluating the reference later results in an lvalue that is precisely the object which was bound to the reference. For example:

int a = 10;
a;             // the value of the expression is immediately discarded
int & r = a;   // this time the value is bound to a reference variable
r;             // this is the same value as a
r = 20;

Evaluating both a and r produces an lvalue of type int, which is the variable a.

Another example:

Foo f();

f();            // a discarded prvalue of type Foo
Foo && r = f(); // this time the value of f() is bound to r
r.do_stuff();

This time, each evaluation of f() produces a distinct value of type Foo (a "temporary object"). The first one is immediately discarded; the second one is bound to the reference r. Evaluating r produces an lvalue of type Foo, namely the temporary object returned from the second function call.

Upvotes: 3

axnsan
axnsan

Reputation: 917

bar2 is identical to bar, since *(char*)(&foo) (value at the address of foo, interpreted as char) is the same as foo itself.

The important thing to understand here, is that a reference is basically a pointer that is automatically dereferenced, and whose address cannot be changed. Or, in other words, an alias for a variable or memory location.

Consider this:

char *c = new char('x');
char &ref = *c;
ref = 'y';
assert(*c == 'y'); //the memory at c was changed through ref
assert(&ref == c); //the address of ref is the same as c, because ref is an alias for the memory at c

char c2 = 'x';
char &ref2 = c2;
char *p = &c2;
c2 = 'y';
assert(p == &ref2);
assert(ref2 == 'y' && *p == 'y');

Upvotes: 2

Related Questions