I understand as with any other variable, the type of a parameter determines the interaction between the parameter and its argument. My question is that what is the reasoning behind why you would reference a parameter vs why you wouldn't? Why are some functions parameters reference and some are not? Having trouble understanding the advantages of doing so, could someone explain?
-
Create a vector holding 2gB of data. Now pass it to a function... a million times. I commend the question. Usually it starts out with "Aren't references and pointers the same?" – WhozCraig Nov 07 '13 at 02:55
-
so is it beneficial to just always reference parameters? or is that not a very smart thing to do? – Tyler Nov 07 '13 at 02:56
-
No. Sometimes there is definite purpose to pass-by-value. Its very situational. Some of those situations can be extremely subtle. – WhozCraig Nov 07 '13 at 02:57
-
Hasn't this same question been asked millions of times, by every programmer new to C++? Why can't you just google it? – Siyuan Ren Nov 07 '13 at 03:00
-
11Very sorry, thought I was using this resource correctly. I just thought it'd be better to ask knowledgeable people that could explain to me rather than just reading material (C++ Primer Fifth Ed. specifically) multiple times and not fully understanding the question "why". – Tyler Nov 07 '13 at 03:08
4 Answers
The ability to pass by reference exists for two reasons:
- To modify the value of the function arguments
- To avoid make copies of an object for performance reasons
Example for modifying the argument
void get5and6(int *f, int *s) // using pointers
{
*f = 5;
*s = 6;
}
this can be used as:
int f = 0, s = 0;
get5and6(&f,&s); // f & s will now be 5 & 6
OR
void get5and6(int &f, int &s) // using references
{
f = 5;
s = 6;
}
this can be used as:
int f = 0, s = 0;
get5and6(f,s); // f & s will now be 5 & 6
When we pass by reference, we pass the address of the variable. Passing by reference is similar to passing a pointer - only the address is passed in both cases.
For eg:
void SaveGame(GameState& gameState)
{
gameState.update();
gameState.saveToFile("save.sav");
}
GameState gs;
SaveGame(gs)
OR
void SaveGame(GameState* gameState)
{
gameState->update();
gameState->saveToFile("save.sav");
}
GameState gs;
SaveGame(&gs);
Since only the address is being passed, the value of the variable (which could be really huge for huge objects) doesn't need to be copied. So passing by reference improves performance especially when:
- The object passed to the function is huge (I would use the pointer variant here so that the caller knows the function might modify the value of the variable)
- The function could be called many times (eg. in a loop)
Also, read on const
references. When it's used, the argument cannot be modified in the function.

- 12,411
- 7
- 56
- 71
Please forget about pointers for now. And take this with a grain of salt.
A reference is the object. When you pass by reference, you pass the object.
When you pass by value, you pass a copy of the object; another object. It may have the same state, but it is a different instance; a clone.
So, it may make sense to pass by reference if you:
- need to modify the object inside the function
- do not need (or want) to modify the object, but would like to avoid copying it just to pass it to a function. This would be a
const
reference.
And it may make sense to pass by value if you:
- want to start from an identical twin, and leave the original twin undisturbed
- do not care about the cost of copying the object (for example, I would not pass an
int
by reference unless I wanted to modify it).
Here, have a look at this code:
#include<iostream>
struct Foo {
Foo() { }
void describe() const {
std::cout<<"Foo at address "<<this<<std::endl;
}
};
void byvalue(Foo foo) {
std::cout<<"called byvalue"<<std::endl;
foo.describe();
}
void byreference(Foo& foo) {
std::cout<<"called byreference"<<std::endl;
foo.describe();
}
int main() {
Foo foo;
std::cout<<"Original Foo"<<std::endl;
foo.describe();
byreference(foo);
byvalue(foo);
}
And compile it like this: g++ example.cpp
Run it: ./a.out
And check the output (the actual addresses may be different in your computer, but the point will remain):
Original Foo
Foo at address 0x7fff65f77a0f
called byreference
Foo at address 0x7fff65f77a0f
called byvalue
Foo at address 0x7fff65f779f0
Notice how the called byreference
address is the same as the Original Foo
address (both are 0x7fff65f77a0f
). And notice how the called byvalue
address is different (it is 0x7fff65f779f0
).
Take it up a notch. Modify the code to look as follows:
#include<iostream>
#include<unistd.h> // for sleeping
struct Foo {
Foo() { }
Foo(const Foo&) {
sleep(10); // assume that building from a copy takes TEN seconds!
}
void describe() const {
std::cout<<"Foo at address "<<this<<std::endl;
}
};
void byvalue(Foo foo) {
std::cout<<"called byvalue"<<std::endl;
foo.describe();
}
void byreference(Foo& foo) {
std::cout<<"called byreference"<<std::endl;
foo.describe();
}
int main() {
Foo foo;
std::cout<<"Original Foo"<<std::endl;
foo.describe();
byreference(foo);
byvalue(foo);
}
Compile it the same way, and notice the output (comments not in the output; included for clarity):
Original Foo
Foo at address 0x7fff64d64a0e
called byreference
Foo at address 0x7fff64d64a0e # this point is reached "immediately"
called byvalue # this point is reached TEN SECONDS later
Foo at address 0x7fff64d64a0f
So, the code is meant to exaggerate the cost of a copy: when you called by reference this cost was NOT incurred. When you called by value you had to wait for ten seconds.
Note: my code was compiled in OS X 10.7.4 using GCC 4.8.1. If you are in windows you may need something different from unitsd.h
to make the sleep
call work.
Maybe this helps.

- 40,844
- 23
- 87
- 135
Pros of using pass by reference: you don't have to create a copy of the data that you are passing just the pointer to it in memory. (huge performance win think if you had a massive object that you passed around). You can "return" multiple values I know some functions in c/c++ return a number and one of the params is a pointer to the data that get's manipulated.
Cons of using pass by reference: you have to be careful modifying the data passed as it could cause side effects that you may or may not want.

- 1,803
- 3
- 17
- 31
By reference is equally to manually pass the variable by pointer, but by reference will not let user to handle the "easy to mess up" pointer.

- 433
- 3
- 15