Как правильно вернуть массив (член класса) в С++?
Я новичок в С++, поэтому это может быть тривиальный вопрос:
В моем классе есть частная переменная-член, которая является массивом. Мне нужно вернуть этот массив, но я не уверен, как это сделать.
class X {
// ...
private: double m_Array[9];
public: double* GetArray() const { return m_Array; }
};
Есть ли проблемы с этим кодом? Это возвращает указатель на член класса, правильно? - так, если я получаю этот массив из экземпляра этого класса и изменяю его (вне класса), будет также изменен исходный массив элементов класса? Если это так, как мне вернуть копию массива?
Ответы
Ответ 1
Это возвращает указатель на член класса, правильно?
Почти - он возвращает указатель на первый элемент массива.
если я получаю этот массив из экземпляра этого класса и изменяю его (вне класса), будет также изменен исходный массив элементов класса?
Это правильно.
Если это так, как мне вернуть копию массива?
Самый простой способ добиться этого - использовать std::array
или std::vector
. Вы должны вернуть ссылку const
к нему - тогда вызывающий абонент избежит затрат на копирование, когда он не понадобится. Пример:
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
В качестве альтернативы, если массив имеет фиксированный размер (как в вашем примере), вы можете вернуть массив, содержащийся в структуре, что и есть std::array
. В противном случае вы можете вернуть указатель (желательно, умный указатель, чтобы избежать утечек памяти), на новый выделенный массив - это более или менее то, что std::vector
.
Ответ 2
Чтобы вернуть копию, массив new
double
должен был бы динамически распределяться, заполнять текущие значения m_Array
и возвращаться вызывающему (указатель на конкретный первый элемент). Вызывающий абонент будет отвечать за delete[]
за возвращаемый массив. Как бы то ни было, вызывающий объект не знает количества элементов в возвращаемом массиве.
Так как это С++, предложите вместо этого изменить std::vector<double>
: это обработает для вас копирование и предоставит вызывающей стороне информацию о количестве double
s.
Ответ 3
Да, при изменении массива вы также измените член класса.
Я бы рекомендовал использовать std::vector вместо c-style array в С++. Это упростит вашу жизнь и сделает код более удобным для чтения. Если по-прежнему есть причина, по которой вы настаиваете на использовании массива, вам нужно выделить новый массив и вернуть указатель на него. Обратите внимание, что это заставит вас работать с динамической памятью и позаботиться о ее освобождении:
public:
double* GetArray() {
double* res = new double[9];
for (int i = 0; i < 9; ++i) {
res[i] = m_Array[i];
}
return res;
}
Вы также можете использовать memcpy для копирования элементов массива.