Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly return an array (class member) in C++?

Tags:

c++

I'm pretty new to C++ so this may be a trivial question:

My class has a private member variable that is an array. I need to return that array, but I'm not sure how to do that properly.

class X {
    // ...
    private: double m_Array[9];
    public: double* GetArray() const { return m_Array; }
};

Is there any problem with this code? This returns a pointer to the class member, right? - so if I fetch that array from an instance of this class and modify it (from outside the class), the original class member array will get changed as well? If that is the case, how do I return a copy of the array instead?

like image 836
Niko Avatar asked Apr 10 '12 11:04

Niko


3 Answers

This returns a pointer to the class member, right?

Almost - it returns a pointer to the first element of the array.

if I fetch that array from an instance of this class and modify it (from outside the class), the original class member array will get changed as well?

That's correct.

If that is the case, how do I return a copy of the array instead?

The easiest way to achieve that is to use std::array or std::vector instead. You should return a const reference to it - then the caller avoid the cost of copying when it's not needed. Example:

class X {
    std::array<double, 9> array;
public:
    std::array<double, 9> const & GetArray() const {return array;}
};

X x;
double d = x.GetArray()[5]; // read-only access, no copy

auto array = x.GetArray();  // get a copy
array[5] = 42;              // modify the copy

Alternatively, if the array has a fixed size (as it does in your example), you could return an array contained in a structure - which is what std::array is. Otherwise you could return a pointer (preferably a smart pointer, to avoid memory leaks) to a newly allocated array - which is more or less what std::vector is.

like image 171
Mike Seymour Avatar answered Nov 07 '22 14:11

Mike Seymour


In order to return a copy a new array of double would need to dynamically allocated, populate with the current values of m_Array and returned to the caller (a pointer to the first element to be specific). The caller would be responsible for delete[]ing the returned array. As it stands, the caller has no knowledge of the number of elements in the returned array.

As this is C++, suggest changing to a std::vector<double> instead: this would handle the copying for you and provide the caller with information regarding the number of doubles.

like image 28
hmjd Avatar answered Nov 07 '22 13:11

hmjd


Yes, when you change the array you will also change the class member.

I would recommend you to use std::vector instead of c-style array in c++. It will make your life way easier and will make the code easier to read. If there is still a reason for you to insist on using array, you need to allocate a new array and return a pointer to it. Note that this will force you to deal with dynamic memory and take care to free it:

public:
  double* GetArray() {
    double* res = new double[9];
    for (int i = 0; i < 9; ++i) {
      res[i] = m_Array[i];
    }
    return res;
  }

You can also use memcpy to copy the elements of the array.

like image 30
Ivaylo Strandjev Avatar answered Nov 07 '22 14:11

Ivaylo Strandjev