Const Reference vs Normal Parameter Passing in C++
This article will discuss the differences between const referencing and normal parameter passing.
To understand const referencing better, we first have to understand the difference between pass by value, pass by reference and pass by const reference.
Pass by Value in C++
Before passing the parameter value, the compiler creates a copy of its memory using a dummy variable, and its value is passed.
#include <bits/stdc++.h>
using namespace std;
void fun(int num) { num = num + 10; }
int main() {
int n = 30;
fun(n);
cout << n << endl;
}
Output:
30
When parameter n
passes through the fun()
function, the compiler creates a memory copy in n
. Since it’s a copy, the original value of n
won’t be modified by the function.
Here, we encounter two disadvantages. We can’t change its value, and a copy of the parameter is created, a wastage of memory.
Pass by Reference in C++
This method eliminates the disadvantages of pass by value method. Instead of creating a dummy parameter and passing its value, we pass the alias of the variable.
So, no memory wastage, and since the alias of the variable is passed, any change done to the variable in the function will get reflected.
#include <bits/stdc++.h>
using namespace std;
void fun(int &num) { num = num + 10; }
int main() {
int n = 30;
fun(n);
cout << n << endl;
}
The value of n
gets affected here.
40
Pass Using Const Reference in C++
Now, we can use the const reference when we do not want any memory waste and do not change the variable’s value.
#include <bits/stdc++.h>
using namespace std;
void fun(const int &num) { num = num + 10; }
int main() {
int n = 30;
fun(n);
cout << n << endl;
}
The above code will throw a compile error as num = num +10
is passed as a const reference. Since it’s const, the parameter becomes read-only, and we can’t change the value of num
.
Output:
[Error] assignment of read-only reference 'num'
Though we mentioned that the parameter’s value couldn’t be changed when the reference is const reference, there are some subtle yet crucial differences.
If a parameter is a const
reference, but the parameter passed was not const, then the parameter’s value may be changed during the function call.
#include <bits/stdc++.h>
using namespace std;
void fun(const int &n) { const_cast<int &>(n) = 40; }
int main() {
int n = 30;
fun(n);
cout << n << endl;
}
We observe that though the parameter passed was not const. The function fun
could change its value with the help of cast.
Output:
40
When a const reference is used to pass a parameter, it includes the extra cost for dereferencing. The worst locality of reference and almost zero opportunities for compiler optimization.
Summary
Syntax - Pass by Value:
double fun(vector<double> my_vector); //pass by value
The underlying object or vector here is copied using its copy constructor. The new object has additional memory allocated to it, and all values and sub-objects are copied and stored separately.
So the above function will copy the vector and make the changes to the copy of that vector rather than the original vector itself. If the object or vector passing is huge, the copying process will become very tedious, wasting our storage and CPU cycles.
Syntax - Pass by Reference:
double fun(vector<double> &my_vector); //pass by reference
The underlying vector is not copied, and the memory address of the vector itself is passed, so changes done by the function will be done directly to the original vector.
This saves both memory and CPU cycles as no new memory is allocated and no (expensive) copy constructors are being called.
Syntax - Pass by Const Reference:
double fun(const vector<double> &my_vector); //pass by const reference
The syntax above is similar to pass by reference only difference is that we can’t modify the underlying values. This solves the problem of not copying and not modifying the values of our object.
Here the reference symbol (&
) states that the vector should not be copied, and the keyword const makes our vector non-modifiable that is read-only.