/* ** $Id: references.cc 843 2008-03-28 01:27:58Z phf $ ** ** Examples for references, new basic concept compared to C, ** similar to pointers but different. :-) */ #include using std::cout; using std::endl; // Start reading in main() below, come back here when main() // tells you to... // Swapping two integers this way doesn't work since copies // are made; so we swap *inside* the function but that does // not affect the variables we mentioned in the call. void swap_value( int a, int b ) { int t = a; a = b; b = t; } // Using pointers we can swap two integers easily. The code // becomes a little more unwieldy because of the "*" stuff, // but otherwise you should be comfortable with this. void swap_pointer( int *a, int *b ) { int t = *a; *a = *b; *b = t; } // With our new references, we can swap fine as well. And // since everything is dereferenced automatically, the code // looks just like the value case above. This is where some // people say "that's dangerous, it looks like only local // stuff is affected, but that's not true". Make up your // own mind. void swap_reference( int &a, int &b ) { int t = a; a = b; b = t; } int main() { // Okay, let's go back to square one and recall that this // creates a variable ("box") that can hold an integer: int a = 10; // In C we spent quite some time on pointers, which are // variables that "hold" other variables. The following // should be familiar: int *p = &a; // We can now access "a" either by naming it directly or // through the pointer "p" using the "*" operator: a = 20; cout << "a: " << a << " p: " << p << " *p: " << *p << endl; *p = 15; cout << "a: " << a << " p: " << p << " *p: " << *p << endl; // In C++ there's a second way to create a second "access // path" to a given variable: References. These things are // declared as follows: int &r = a; // Note that the "&" does not stand for "make into a pointer" // or "take the address of" or any such thing. It simply means // "declare r to be a reference to an int variable" much like // "int *p" means "declare p to be a pointer to an int variable". // Now check out what we can do: a = 13; cout << "a: " << a << " p: " << p << " *p: " << *p << " r: " << r << endl; r = 17; cout << "a: " << a << " p: " << p << " *p: " << *p << " r: " << r << endl; // Note how "*p" as well as "r" are different ways to talking // about the variable "a"; if we change "*p" or "r" we also // change the content of "a" itself. There are two ways you // can think about references, both correct-ish: // // - references create a new name for an existing variable, // whatever we do with the reference we are doing with the // original variable // // - references are like pointers that cannot be changed (to // point to a different variable) and need not be explicitly // dereferenced (no "*" operator) // // It's debatable why exactly the C++ people thought they need to // add references, everything we can do with references we could // already do with pointers. Some people even dislike references // because they "behave like pointer but don't look like them". // In any case, since references are used a lot in C++ and the // STL, you need to learn them anyway; whether you use them in // your own code is really up to you. // Note that while we can introduce a pointer without initializing // it, we can't create a reference that way. This works fine: int *q; q = NULL; // But this doesn't work (try it): // int &s; // We can use references as parameters, in which case they allow // us to change variables outside the function, much like pointers. // We'll illustrate this with a few swap() functions again. int x = 10; int y = 20; cout << "x: " << x << " y: " << y << endl; swap_value( x, y ); cout << "x: " << x << " y: " << y << endl; swap_pointer( &x, &y ); cout << "x: " << x << " y: " << y << endl; swap_reference( x, y ); cout << "x: " << x << " y: " << y << endl; }