Как использовать динамически создаваемый одномерный массив по ссылке на двумерный массив только со стандартной библиотекой?
Как использовать динамически создаваемый одномерный массив по ссылке на двумерный массив только со стандартной библиотекой?
это может быть сделано путем создания перегрузки operator []
?
пример: я хочу сформировать матрицу, создав одномерный массив, а затем использовать его в виде двумерного массива.
// in class, a matrix created by:
p = new double[m*n]();
when using it, I'd like to use it like this:
for(i=0; i<10; i++)
for(j=0; j<10; j++)
a[i][j] = 0.0;
я думал об использовании перегрузки оператора operator []
и переменная проверка, чтобы подтвердить, появился ли "[]" впервые или нет, но выше оказался
ошибка: "недопустимые типы
double[int]
для массива "
это возможно сделать так?
3 ответа
Это легко сделать с operator()
если вы не против фортрановского синтаксиса. Мне нравится использовать вспомогательный класс, как это:
template <class T>
class Indexer2D
{
public:
Indexer2D(size_t w, size_t h, T *theData) :
width(w), height(h), data(theData)
{ }
T& operator() (size_t row, size_t col)
{
return data[(width * row) + col];
}
private:
size_t width;
size_t height;
T *data;
};
Ваш код будет выглядеть так:
p = new double[m*n]();
Indexer2D<double> pMatrix(m, n, p);
pMatrix(1,4) = 23.9;
Это дает хороший синтаксис с минимальным выделением памяти. Он не проверяет ваши границы, но это было бы легко сделать. Если вам нужен минимальный вес, вам не нужно хранить высоту.
Я предлагаю либо с помощью ручного расчета индекса:
a = new double[m*n]();
for(i=0; i<10 && i<m; i++)
for(j=0; j<10 && j<n; j++)
a[i*n+j] = 0.0;
Обратный расчет будет: i = index/n, j = index % n
В качестве альтернативы используйте valarray:
#include <valarray>
// ....
a[std::slice(i, n, m)][j] = 0.0;
Лучшие результаты могут быть достигнуты с помощью std::gslice
(который является обобщенным срезом, принимая несколько измерений). У меня нет времени, чтобы разработать полный пример сейчас.
Вот ссылка на довольно мощный образец Н. Йосуттиса:
Если вы можете использовать дополнительную память, вы можете сделать это:
// Allocate 1D array
double * p = new double[m*n]();
// Allocate pointers for 2D reference
double ** p2D = new double *[m];
// set 2D pointers to allocated memory
for (i = 0; i < m; i++)
p2D[i] = &p[i * n];
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
p2D[i][j] = 0.0;