Reputation: 143
I'm new to C++ and I couldn't find explanation about how to pass an array of objects as a reference. When I pass it regularly, it only updates the values at the scope of unside the function, unlike in C#, where it's automatically passed by reference. Thanks.
Upvotes: 0
Views: 2528
Reputation: 27528
You can pass a raw array by reference, even if the syntax is somewhat ugly:
#include <iostream>
void ModifyArray(int (&array)[5])
{
array[4] = 0;
}
int main()
{
int array[5] = { 1, 2, 3, 4, 5 };
ModifyArray(array);
std::cout << array[4] << "\n";
}
Using std::array
makes the syntax simpler:
#include <iostream>
#include <array>
void ModifyArray(std::array<int, 5>& array)
{
array[4] = 0;
}
int main()
{
std::array<int, 5> array = { 1, 2, 3, 4, 5 };
ModifyArray(array);
std::cout << array[4] << "\n";
}
If you try to pass a raw array "directly", then you are really passing a pointer to the first element of the array. This is informally called "decaying". The following apparently works, but there is a caveat:
#include <iostream>
void ModifyArray(int array[5]) // works?
{
array[4] = 0;
}
int main()
{
int array[5] = { 1, 2, 3, 4, 5 };
ModifyArray(array);
std::cout << array[4] << "\n";
}
The caveat is that the size information of the argument, i.e. the [5]
part, is ignored. Because, as we have just established, the function does not take an array but a pointer.
Try the following:
#include <iostream>
void ModifyArray(int array[5]) // works?
{
array[4] = 0; // problem!
}
int main()
{
int array[3] = { 1, 2, 3 };
ModifyArray(array);
}
This program compiles fine but invokes undefined behaviour because you try to access the 5th element of a 3-element array. It's no different than this:
#include <iostream>
void ModifyArray(int* array)
{
array[4] = 0; // problem!
}
int main()
{
int array[3] = { 1, 2, 3 };
ModifyArray(array);
}
When you pass collections of elements around, always use std::vector
or std::array
by default and consider alternatives if you really you need them.
Upvotes: 3
Reputation: 2014
Passing an array by reference is typically unnecessary. When you declare an array parameter to a function, it is the same as declaring the parameter to be a pointer, so you have a level of indirection anyway.
When you pass an object like std::vector
or std::array
, you can pass it by reference like any old parameter, by putting a &
before the parameter name.
Here's an example of passing a vector to a function by reference and observing that the contained values are changed for the caller:
#include <vector>
#include <iostream>
void double_all(std::vector<int>& values) {
for (int& v: values)
v += v;
}
int main() {
std::vector<int> values = {0, 1, 2, 3, 4};
double_all(values);
for (int v: values)
std::cout << v << "\n";
}
Upvotes: 1
Reputation: 409176
If you haven an actual array like e.g.
MyClass array[X];
Then when you pass it to a function is decays to a pointer, so in a way it's already passed by reference. It doesn't matter that the function declares the argument like an array, it's still going to be a pointer.
So the two following function declarations are equivalent:
void my_function(MyClass array[X]);
and
void my_function(MyClass* array);
If you have a dynamically allocated array, like e.g.
MyClass* array = new MyClass[X];
then array
already is a pointer and don't need to be passed by reference, unless you want to modify the actual pointer.
And if you have an object of type std::vector
or std::array
(which I recommend over using pointers or plain arrays) then you use the normal ampersand &
to pass it by reference.
Upvotes: 3