我最初问过using nested std::array to create an multidimensional array without knowing dimensions or extents until runtime,但是有The XY Problem试图用std :: array来完成它。
问题One-line initialiser for Boost.MultiArray和How do I make a multidimensional array of undetermined size a member of a class in c++?及其答案提供了一些有用的信息,告诉我们如何使用Boost :: MultiArray来避免在运行时知道维度的范围,但未能证明如何使用一个类成员,可以存储一个数组(在运行时创建),其数据和范围在运行时才会知道。
答案 0 :(得分:3)
避免使用多维数组:
template<typename T>
class Matrix
{
public:
Matrix(unsigned m, unsigned n)
: n(n), data(m * n)
{}
T& operator ()(unsigned i, unsigned j) {
return data[ i * n + j ];
}
private:
unsigned n;
std::vector<T> data;
};
int main()
{
Matrix<int> m(3, 5);
m(0, 0) = 0;
// ...
return 0;
}
3D访问(在适当的3D矩阵中)将是:
T& operator ()(unsigned i, unsigned j, unsigned k) {
// Please optimize this (See @Alexandre C)
return data[ i*m*n + j*n + k ];
}
获取任意维度和范围将遵循该方案并添加重载(和维度/范围信息)和/或利用可变参数模板。
你可以避免使用很多维度(即使在C ++ 11中)并用std :: vector替换参数。例如:T&amp; operator(std :: vector indices)。 每个维度(除了最后一个)都有一个存储在向量n中的扩展(作为上面2D示例中的第一个维度)。
答案 1 :(得分:1)
是。使用单个指针成员。
n 多维数组实际上是一个指针。所以你可以使用强制转换动态 n 数组,并将此数组放入成员指针中。
在你的课堂上应该是这样的
int * holder;
void setHolder(int* anyArray){
holder = anyArray;
}
使用:
int *** multy = new int[2][1][56];
yourClass.setHolder((int*)multy);
答案 2 :(得分:1)
您可以通过至少两种方式解决问题,具体取决于您的偏好。首先 - 你不需要Boost库,你可以自己动手。
class array{
unsigned int dimNumber;
vector<unsigned int> dimSizes;
float *array;
array(const unsigned int dimNumber, ...){
va_list arguments;
va_start(arguments,dimNumber);
this->dimNumber = dimNumber;
unsigned int totalSize = 1;
for(unsigned int i=0;i<dimNumber;i++)
{
dimSizes.push_back(va_arg(arguments,double));
totalSize *= dimSizes[dimSizes.size()-1];
}
va_end(arguments);
array = new float[totalSize];
};
float getElement(unsigned int dimNumber, ...){
va_list arguments;
va_start(arguments,dimNumber);
unsgned int elementPos = 0, dimAdd = 1;
for(unsigned int i=0;i<dimNumber;i++)
{
unsigned int val = va_arg(arguments,double);
elementPos += dimAdd * val;
dimAdd *= dimsizes[i];
}
return array[elementPos]
};
};
设置元素值将是相同的,您只需指定新值。当然你可以使用你想要的任何类型,而不仅仅是浮动...当然记得在析构函数中delete[]
数组。
我没有测试过代码(只是从内存中直接写下来),所以在计算位置时可能存在一些问题,但我相信如果遇到它们你会修复它们。这段代码应该给你一般的想法。
第二种方法是创建一个dimension
类,它将存储一个存储子维度的vector<dimension*>
。但这有点复杂,而且写得太长了。
答案 3 :(得分:0)
您可以使用具有相同数量索引的1D数组,而不是多维数组。我无法测试此代码,但我希望它可以工作或让您了解如何解决您的问题。您应该记住,编译时没有恒定长度的数组应该通过malloc()
分配,或者您的代码可能无法在其他计算机上运行。
(也许你应该为下面的代码创建一个类array
)
#include <malloc.h>
int* IndexOffset; //Array which contains how many indices need to be skipped per dimension
int DimAmount; //Amount of dimensions
int SizeOfArray = 1; //Amount of indices of the array
void AllocateArray(int* output, //pointer to the array which will be allocated
int* dimLengths, //Amount of indices for each dimension: {1D, 2D, 3D,..., nD}
int dimCount){ //Length of the array above
DimAmount = dimCount;
int* IndexOffset = (int*) malloc(sizeof(int) * dimCount);
int temp = 1;
for(int i = 0; i < dimCount; i++){
temp = temp * dimLengths[i];
IndexOffset[i] = temp;
}
for(int i = 0; i < dimCount; i++){
SizeOfArray = SizeOfArray * dimLengths[i];
}
output = (int*)malloc(sizeof(int) * SizeOfArray);
}
要获取索引,请使用此选项:
int getArrayIndex(int* coordinates //Coordinates of the wished index as an array (like dimLengths)
){
int index;
int temp = coordinates[0];
for(int i = 1; i < DimAmount; i++){
temp = temp + IndexOffset[i-1] * coordinates[i];
}
index = temp;
return index;
}
在您不再需要时,请记住free()
您的阵列:
for(int i = 0; i < SizeOfArray; i++){
free(output[i]);
}
free(output);