In C++ by default all arguments are passed
by value. This means that the variable used in the function gets a
copy of the data used in the function call.
1 2 3 4 5 6 7 8 9 10
|
void Increment(int v)
{
v++;
}
int main()
{
int a = 5;
Increment(a);
}
|
Here the value of a (5) is passed as the argument to function Increment. In Increment the variable v receives the value of a - is copied. There is no 'connection' between a and v. Any changes made to v in Increment() do not alter the value of a in main(). a can be const or non-const or r-value etc.
If you want Increment() to affect the value of the passed argument in the calling function then you pass by reference.
1 2 3 4 5 6 7 8 9 10
|
void Increment(int& v)
{
v++;
}
int main()
{
int a = 5;
Increment(a);
}
|
Now when the valve of v is changed in Increment(), the value of a in main() is also changed. This is pass by reference. a cannot be const or r-value.
However this means that a in main() cannot be const (or r-value) as it can be when passed as value (as a copy is done). If the size of the data that is being passed is large, then passing by value means doing a copy which is expensive in terms of performance. Pass by reference has much better performance. In order to accommodate both (pass by reference by performance and const data), then you use
1 2 3 4 5 6 7 8 9 10
|
void Increment(const int& v)
{
//v++; This now generates an error as v is const
std::cout v << std:endl;
}
int main()
{
Increment(5); // This is OK now as passed by const ref
}
|
Behind the scenes, pass by reference is usually implemented using pointers (pass by value of a pointer). So only the number of bytes for a pointer is copied - not the size of the passed type. This can drastically improve performance for types like string. vector etc and why you often seen const std::string& as the type of a function argument.