Anton Raskin
Anton Raskin

Reputation: 143

Passing objects array by reference

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

Answers (3)

Christian Hackl
Christian Hackl

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

ben
ben

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

Some programmer dude
Some programmer dude

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

Related Questions