Revisit parameter passing
The C way of parameter passing
Let's take a look at the C way of passing by reference. There is no
pass by reference in C, so to accomplish this when passing in a
variable, say an int, you directly pass the address and receive
it as a pointer. Look at an example of this with the memory picture:
main() {
int i = 10;
messAround(&i); // read as the "address of i"
cout << i << << endl; // displays 20
...
}
void messAround(int* p) {
*p += 10; // must dereference to get at the int
}
Memory when function CALLED: Memory AFTER function performs:
messAround: messAround:
main: +----------+ main: +----------+
+----+ | __ | +----+ | __ |
i | 10 | <-------|--| p | i | 20 | <-------|--| p |
+----+ | -- | +----+ | -- |
+----------+ +----------+
Contrast this code and this memory picture with pass by reference:
main() {
int i = 10;
messAround(i);
cout << i << << endl; // displays 20
...
}
void messAround(int& num) {
num += 10; // compiler automatically dereferences
}
Memory when function CALLED: Memory AFTER function performs:
messAround: messAround:
main: +----------+ main: +----------+
+----+ | __ | +----+ | __ |
i | 10 | <-------|--| num | i | 20 | <-------|--| num |
+----+ | -- | +----+ | -- |
+----------+ +----------+
Notice that the pictures looks identical. In the first example,
p is a pointer. In the second example, num is an int (a reference).
The only difference is how you access the contents of   i .
With pointers, the programmer is responsible for dereferencing.
With references, the compiler automatically dereferences.
Some C programmers don't like pass by reference because they say
you can't tell if it's pass by value or pass by reference in
the caller . This is true, but C++ programmers are used
to looking to see if it's pass by value or by reference in
the function
Pass a pointer by reference
There will be times when you will want to pass
a pointer by reference. If you have a pointer variable to some object,
you may need to change the contents of the pointer. In other
words, you may need to make the pointer point to some other object.
That's regular old pass by reference, but there's another level
of complexity because it's essentially a reference of a pointer, or
some say a pointer to a pointer.
Here's a picture of that sort of thing:
client program:
SomeClass* p;
// p gets initialized and now points to a good SomeClass object
doSomething(p);
...
}
void doSomething(SomeClass*& param) {
SomeClass* temp = param;
SomeClass* q = new SomeClass(...); // instantiate new SomeClass object
param = q;
delete temp; // don't want memory leak
q = temp = NULL; // safety
...
}
Memory when function CALLED and temp and q are set:
+---------+
|data | doSomething:
|inside of| +-----------+
|SomeClass| | __ |
|object | <--------|- | q |
+---------+ |+--+ |
client: | |
+--+ +---------+ | __ |
p | -|----> |data | <--------|- | temp |
+--+ |inside of| |+--+ |
^ |SomeClass| | |
| |object | | |
\ +---------+ | __ |
----------------------------|- | param |
|+--+ |
+-----------+
The parameter, param, is a reference of the pointer p,
so it is set to the address of   p , not what   p   points to.
This is essentially a pointer to a pointer.
The temp variable is set to param, and since param is a reference,
it is automatically dereferenced, so   q   gets the contents
of param, which is the pointer to the object.
Now do the assignment:   param = q;
Again, since param is a reference,
it is automatically dereferenced, so the contents of param are
changed, and now it points to the same object   q   points to.
+---------+
|data | doSomething:
|inside of| +-----------+
^|SomeClass| | __ |
/ |object | <--------|- | q |
/ +---------+ |+--+ |
client: / | |
+--+ / +---------+ | __ |
p | -|- |data | <--------|- | temp |
+--+ |inside of| |+--+ |
^ |SomeClass| | |
| |object | | |
\ +---------+ | __ |
----------------------------|- | param |
|+--+ |
+-----------+
After cleaning up by deleting the memory that temp points to,
and setting q and temp to NULL, we have
cleanly changed the contents of   p .
The dots where the object used to be mean that the memory isn't
really gone, but we have deallocated it, and it can be used elsewhere.
+---------+
|data | doSomething:
|inside of| +-----------+
^|SomeClass| | ____ |
/ |object | ||NULL|q |
/ +---------+ |+----+ |
client: / | |
+--+ / ......... | ____ |
p | -|- ........... ||NULL|temp |
+--+ ........... |+----+ |
^ ........... | |
| ........... | |
\ ......... | __ |
----------------------------|- | param |
|+--+ |
+-----------+