I finally understood passing-by-value and passing-by-reference when I realized pointers are also passed by value, and when I was told that references are actually implemented as constant pointers. So, that means, everything is passed by value:
1)When you pass an object to a function, a copy is made for the function, so when you change the object inside the function, you are changing a copy, and the original is unaffected. When the function ends, the copy is destroyed.
2) When you pass a pointer to a function, you are passing an address in memory. Just like with an object, a copy of the pointer is made for the function. And, just like with passing an object, if you try to change the pointer, you only change the copy. The following code demonstrates that:
Code:
void func(int* p)
{
int* pi = new int(10);
cout<<pi<<endl;
p = pi;
}
int main()
{
int i = 10;
int* p = &i;
cout<<p<<endl;
func(p);
cout<<p<<endl;
return 0;
}
The output should show that the address remains unchanged. However, if you use the pointer to change the object at that address, then you will make permanent changes to the object. To make changes to an object at a certain address, it doesn't matter whether you have a copy of the address or the original address. Furthermore, when the copy of the address gets destroyed, it doesn't affect the object at that address.
3) A reference acts like a constant pointer(or is implemented as a constant pointer). So, once again, a copy of the pointer is made for the function. However, unlike the example above, you cannot try to change the address stored in the pointer without getting a compiler error. A constant pointer means that you cannot change the address that is stored in the pointer.
Code:
int main()
{
int i = 10;
int& r = i;
cout<<r<<endl;
int n = 100;
r = &n; //error
return 0;
}
It is interesting to note that you can change the value at the address stored in the reference. In other words, a reference points to a constant spot in memory, but the value that occupies that spot can change:
Code:
int main()
{
int i = 10;
int& r = i;
cout<<r<<endl;
int n = 100;
r = n; //ok--changed the value at the address pointed to by r
cout<<r<<endl;
return 0;
}
Note: a constant pointer can be null, but as noted previously a reference cannot be null, so a reference does not behave indentically to a constant pointer.
See here for a nice illustration:
http://www.dgp.toronto.edu/~patrick/...ntersVsRef.pdf
However, his conclusion is wrong:
Therefore, to summarize, a pointer can point to many different objects during its lifetime, a reference
can refer to only one object during its lifetime.
Here is a program where a reference is made to refer to two objects:
Code:
class Apple
{
public:
int num;
Apple(int n):num(n){}
};
int main()
{
Apple a(10);
Apple& r = a;
cout<<r.num<<endl;
Apple b(50);
r = b;
cout<<r.num<<endl;
return 0;
}