template <typename T, int n>
struct Pointer {
typedef typename Pointer<T, n - 1>::Type *Type;
};
template <typename T>
struct Pointer<T, 1> {
typedef T *Type;
};
Pointer<int, 2>::Type pointer = new int*[10];
Указатель на [Указатель на]
Можно определить указатель на массив указателей любой размерности
Код:
Type *p;// кратность = 1
Type **p;// кратность = 2
Type ***p;// кратность = 3
Type **p;// кратность = 2
Type ***p;// кратность = 3
Код:
p[i]; // для Type *p;
p[i][j]; // для Type **p;
p[i][j][k];// для Type ***p;
p[i][j]; // для Type **p;
p[i][j][k];// для Type ***p;
Цитата: Meander
Понимаю, что можно определить столько обычных классов, сколько размерностей требуется, просто интересно, позволяет ли C++ решить задачу описанной параметризации?
Код:
Код:
// Не надо использовать нетипизированные константы (прим. автора ответа)
#define HEIGHT 5
#define WIDTH 3
#define DEPTH 7
int main() {
double ***p3DArray;
// Выделение памяти
p3DArray = new double**[HEIGHT];
for (int i = 0; i < HEIGHT; ++i) {
p3DArray[i] = new double*[WIDTH];
for (int j = 0; j < WIDTH; ++j)
p3DArray[i][j] = new double[DEPTH];
}
// Указание значений
p3DArray[0][0][0] = 3.6;
p3DArray[1][2][4] = 4.0;
// Освобождение памяти
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j)
delete [] p3DArray[i][j];
delete [] p3DArray[i];
}
delete [] p3DArray;
return 0;
#define HEIGHT 5
#define WIDTH 3
#define DEPTH 7
int main() {
double ***p3DArray;
// Выделение памяти
p3DArray = new double**[HEIGHT];
for (int i = 0; i < HEIGHT; ++i) {
p3DArray[i] = new double*[WIDTH];
for (int j = 0; j < WIDTH; ++j)
p3DArray[i][j] = new double[DEPTH];
}
// Указание значений
p3DArray[0][0][0] = 3.6;
p3DArray[1][2][4] = 4.0;
// Освобождение памяти
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j)
delete [] p3DArray[i][j];
delete [] p3DArray[i];
}
delete [] p3DArray;
return 0;
Код:
T* CreateArray(long firstSize)
T** CreateArray(long firstSize, long secondSize)
T*** CreateArray(long firstSize, long secondSize, long thirdSize)
T** CreateArray(long firstSize, long secondSize)
T*** CreateArray(long firstSize, long secondSize, long thirdSize)
Код:
double ***p;
Код:
typedef double* p1;
typedef p1* p2;
typedef p2* p3;
//создаем переменную типа p3
p3 p;
//для p можно задать размеры как обычно
typedef p1* p2;
typedef p2* p3;
//создаем переменную типа p3
p3 p;
//для p можно задать размеры как обычно
Назначение простое. Создать класс (конструктор принимает размерность массива) содержащий переменную выше описанного типа и метод задающий размеры массива по всем измерениям. Если эта переменная открытый член, то обращаться к ней можно как к обычному многомерному массиву. Вот ты привел пример создания трехмерного массива, а если построить описанный мной класс, то создание массива любой размерности было бы короче. Понимаю, что можно определить столько обычных классов, сколько размерностей требуется, просто интересно, позволяет ли C++ решить задачу описанной параметризации?
Неужели проще написать метод, который расчитывает размеры массива, создать экземпляр фабрики (или синглтонить её), делегировать метод фабрике, вызвать конструктор класса через фабрику?! ЗАЧЕМ?!
Код:
#include "ArrayFactory.hpp"
typedef double* DoubleArray;
typedef double** Double2DArray;
typedef double*** Double3DArray;
int _tmain(int argc, _TCHAR* argv[])
{
DoubleArray arr1d = ArrayFactory::CreateArray<double>(5);
Double2DArray arr2d = ArrayFactory::CreateArray<double>(5, 10);
Double3DArray arr3d = ArrayFactory::CreateArray<double>(5, 10, 28);
ArrayFactory::DeleteArray<double>(arr1d);
ArrayFactory::DeleteArray<double>(arr2d);
ArrayFactory::DeleteArray<double>(arr3d);
return 0;
}
// ArrayFactory.hpp
#pragma once
class ArrayFactory
{
public:
template<typename T>
static T* CreateArray(int x)
{
return new T[x];
}
template<typename T>
static T** CreateArray(int y, int x)
{
T** result = new T*[y];
for (int i = 0; i < y; i++)
result[i] = new T[x];
return result;
}
template<typename T>
static T*** CreateArray(int z, int y, int x)
{
T*** result = new T**[z];
for (int i = 0; i < z; i++)
{
result[i] = new T*[y];
for (int k = 0; k < y; k++)
result[i][k] = new T[x];
}
return result;
}
};
typedef double* DoubleArray;
typedef double** Double2DArray;
typedef double*** Double3DArray;
int _tmain(int argc, _TCHAR* argv[])
{
DoubleArray arr1d = ArrayFactory::CreateArray<double>(5);
Double2DArray arr2d = ArrayFactory::CreateArray<double>(5, 10);
Double3DArray arr3d = ArrayFactory::CreateArray<double>(5, 10, 28);
ArrayFactory::DeleteArray<double>(arr1d);
ArrayFactory::DeleteArray<double>(arr2d);
ArrayFactory::DeleteArray<double>(arr3d);
return 0;
}
// ArrayFactory.hpp
#pragma once
class ArrayFactory
{
public:
template<typename T>
static T* CreateArray(int x)
{
return new T[x];
}
template<typename T>
static T** CreateArray(int y, int x)
{
T** result = new T*[y];
for (int i = 0; i < y; i++)
result[i] = new T[x];
return result;
}
template<typename T>
static T*** CreateArray(int z, int y, int x)
{
T*** result = new T**[z];
for (int i = 0; i < z; i++)
{
result[i] = new T*[y];
for (int k = 0; k < y; k++)
result[i][k] = new T[x];
}
return result;
}
};
P.S. И да, как я уже сказал, ты можешь написать метод void* CreateArray(int demensions, delegate) и приводить его результаты к своему типу. Но ты не сможешь заставить компилятор типизировать этот указатель, если demensions расчитываются в процессе работы - как ты себе это представляешь? :)
Код:
#include <iostream>
#include <stdlib.h>
template <class T>
class Array {
private:
int dim, //число измерений
*siz; //размеры измерений
T *arr;//главный вектор
public:
Array(int,...);
~Array(void);
T& operator()(int,...);
};
template <class T>
Array<T>::Array(int x,...){
int *p = &x, i=0, len = 1;
dim = 0;
while(*p){
dim++;
p++;
}
siz = new int [dim];
while(*p){
siz[i] = (*p);
len *= siz[i];
p++;
i++;
}
arr = new T [len];
}
template <class T>
Array<T>::~Array(void){
delete [] siz; siz = NULL;
delete [] arr; arr = NULL;
}
template <class T>
T& Array<T>::operator()(int x,...){
int k = 0, m = 1, *p = &x, i = 0, l;
while(*p){
l = (*p);
k = k + l * m;
m = m * siz[i];
p++;
i++;
}
return arr[k];
}
//1 x
//2 y*X + x
//3 z*X*Y + y*X + x
//4 k*X*Y*Z + z*X*Y + y*X + x
int main(int argc, char *argv[]) {
int X = 5,
Y = 2,
Z = 2;
Array<double> array(X,Y,Z);
for(int x=0;x<X;x++)
for(int y=0;y<Y;y++)
for(int z=0;z<Z;z++){
array(x,y,z) = z*X*Y +y*X + x;
}
for(int x=0;x<X;x++)
for(int y=0;y<Y;y++)
for(int z=0;z<Z;z++){
double k = array(x,y,z);
std::cout << k << '\n';
}
system("pause");
return 0;
}
#include <stdlib.h>
template <class T>
class Array {
private:
int dim, //число измерений
*siz; //размеры измерений
T *arr;//главный вектор
public:
Array(int,...);
~Array(void);
T& operator()(int,...);
};
template <class T>
Array<T>::Array(int x,...){
int *p = &x, i=0, len = 1;
dim = 0;
while(*p){
dim++;
p++;
}
siz = new int [dim];
while(*p){
siz[i] = (*p);
len *= siz[i];
p++;
i++;
}
arr = new T [len];
}
template <class T>
Array<T>::~Array(void){
delete [] siz; siz = NULL;
delete [] arr; arr = NULL;
}
template <class T>
T& Array<T>::operator()(int x,...){
int k = 0, m = 1, *p = &x, i = 0, l;
while(*p){
l = (*p);
k = k + l * m;
m = m * siz[i];
p++;
i++;
}
return arr[k];
}
//1 x
//2 y*X + x
//3 z*X*Y + y*X + x
//4 k*X*Y*Z + z*X*Y + y*X + x
int main(int argc, char *argv[]) {
int X = 5,
Y = 2,
Z = 2;
Array<double> array(X,Y,Z);
for(int x=0;x<X;x++)
for(int y=0;y<Y;y++)
for(int z=0;z<Z;z++){
array(x,y,z) = z*X*Y +y*X + x;
}
for(int x=0;x<X;x++)
for(int y=0;y<Y;y++)
for(int z=0;z<Z;z++){
double k = array(x,y,z);
std::cout << k << '\n';
}
system("pause");
return 0;
}
Код:
const int size = 10;
void* createArray(int dim) {
if (dim==1) return new int[size];
void* res = new void*[size];
for (int i=0; i<size; ++i) res[i] = createArray(dim - 1);
return res;
}
void printArray(void* array) {
if (typeid(array) == typeid(int*))
for (int i=0; i<size; ++i) cout << array[i] << endl;
else
for (int i=0; i<size; ++i) printArray(array[i]);
}
void* createArray(int dim) {
if (dim==1) return new int[size];
void* res = new void*[size];
for (int i=0; i<size; ++i) res[i] = createArray(dim - 1);
return res;
}
void printArray(void* array) {
if (typeid(array) == typeid(int*))
for (int i=0; i<size; ++i) cout << array[i] << endl;
else
for (int i=0; i<size; ++i) printArray(array[i]);
}
Попробую, правда меня терзают смутные сомнения, что обращение к конкретной ячейке будет мудреным.
Цитата: Der Meister
Но лучше давайте не надо.
Почему, ведь теперь можно создавать массив любой размерности одним кликом мыши?