Est-il possible en c ++ pour une classe d’avoir un membre qui est un tableau multidimensionnel dont les dimensions et les étendues ne sont pas connues avant l’exécution?

A l’origine, j’avais demandé à l’ aide de std :: array nested de créer un tableau multidimensionnel sans connaître les dimensions ou les étendues jusqu’au moment de l’exécution, mais cela posait un problème .

Les questions Initialisation sur une ligne pour Boost.MultiArray et comment puis-je faire d’un tableau multidimensionnel de taille indéterminée un membre d’une classe en c ++? et leurs réponses fournissent des informations utiles sur l’utilisation de Boost :: MultiArray afin d’éviter d’avoir à connaître l’étendue des dimensions au moment de l’exécution, sans toutefois démontrer comment un membre de classe pouvant stocker un tableau (créé à l’exécution) dont les dimensions et les étendues ne sont pas connues avant l’exécution.

Évitez simplement les tableaux multidimensionnels:

template class Masortingx { public: Masortingx(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 data; }; int main() { Masortingx m(3, 5); m(0, 0) = 0; // ... return 0; } 

Un access 3D (dans une masortingce 3D appropriée) serait:

 T& operator ()(unsigned i, unsigned j, unsigned k) { // Please optimize this (See @Alexandre C) return data[ i*m*n + j*n + k ]; } 

L’obtention de dimensions et d’étendue arbitraires suivrait le schéma et appendait des surcharges (et des informations de dimension / étendue) et / ou tirerait parti des modèles variadiques.

Ayant beaucoup de dimensions que vous pouvez éviter ci-dessus (même en C ++ 11), remplacez les arguments par un std :: vector. Ex: T & opérateur (std :: indices vectoriels). Chaque dimension (à part la dernière) aurait une extension stockée dans un vecteur n (comme la première dimension dans l’exemple 2D ci-dessus).

Oui. avec un seul membre du pointeur.

Un tableau multidimensionnel est en fait un pointeur. vous pouvez donc allouer un tableau dynamic n avec casting, et placer ce tableau dans le pointeur de membre.

Dans votre classe devrait être quelque chose comme ça

 int * holder; void setHolder(int* anyArray){ holder = anyArray; } 

utilisation:

 int *** multy = new int[2][1][56]; yourClass.setHolder((int*)multy); 

Vous pouvez résoudre le problème de deux manières au moins, selon vos préférences. Tout d’abord, vous n’avez pas besoin de la bibliothèque Boost et vous pouvez le faire vous-même.

 class array{ unsigned int dimNumber; vector 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 

Définir une valeur d'élément serait la même chose, il vous suffira de spécifier la nouvelle valeur. Bien sûr, vous pouvez utiliser n'importe quel type, pas seulement float ... et bien sûr, n'oubliez pas de delete[] le tableau dans le destructeur.

Je n'ai pas testé le code (je l'ai simplement écrit directement ici de mémoire), il peut donc y avoir des problèmes avec le calcul de la position, mais je suis sûr que vous allez les réparer si vous les rencontrez. Ce code devrait vous donner une idée générale.

La deuxième façon serait de créer une classe de dimension , qui stockerait un vector qui stockerait des sous-dimensions. Mais c'est un peu compliqué et trop long pour écrire ici.

Au lieu d’un tableau multidimensionnel, vous pouvez utiliser un tableau 1D avec un nombre égal d’indices. Je ne pouvais pas tester ce code, mais j’espère que cela fonctionnera ou vous donnera une idée de la façon de résoudre votre problème. N’oubliez pas que les tableaux, qui n’ont pas une longueur constante à partir du moment de la compilation, doivent être alloués via malloc() ou votre code pourrait ne pas s’exécuter sur d’autres ordinateurs. (Peut-être devriez-vous créer un array classe pour le code ci-dessous)

 #include  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); } 

Pour obtenir un index, utilisez ceci:

 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; } 

N'oubliez pas de free() votre tableau dès que vous n'en avez plus besoin:

 for(int i = 0; i < SizeOfArray; i++){ free(output[i]); } free(output);