C++ is an example of a message-passing paradigm language, which means that objects and values are passed to functions, which then return further objects and values based on the input data.
One of the benefits of C++ is that it allows very fine grained control over these function interfaces, as well as how the passed objects are stored and manipulated.
In C++ there are three different ways to pass data to a function.
All have different characteristics when it comes to efficiency, storage and behaviour.
When an object (or built-in type) is passed by value to a function, the underlying object is copied using its copy constructor.
Passing an object by value also means that any modifications made to the object, within the scope of the function being passed the object, will occur on the copied object and not on the object that was passed.
Example: Consider a norm function which calculates the Euclidean norm of a vector of double values. The function returns one double precision value (“the norm”) and takes the vector as a parameter. The following code shows the vector being passed by value:
double euclid_norm(vector<double> my_vector);
NOTE: This will copy the vector and will make any underlying changes to the copy of that vector, rather than the vector itself.
When an object (or built-in type) is passed by reference to a function, the underlying object is not copied.
If the function being passed the object now modifies the object in any way, the original object will reflect those modifications, rather than a copy of the object.
Here is the same euclid_norm function modified to pass the vector by reference.
double euclid_norm(vector<double>& my_vector);
To solve the problem of not copying AND not modifying the underlying data a technique known as passing by reference to const is used.
double euclid_norm(const vector<double>& my_vector);
NOTE: Our interface is now much more precise about its intent.
Nearly all instances of mathematical “read only” functions should be prefixed in this manner.