C ++ частный класс динамический n-мерный массив

Я искал ответ вокруг StackOverlow, но я не нашел такого, поэтому я надеюсь, что это не дублирование какого-либо сообщения здесь.

Итак, у меня есть следующая проблема.
допустим, у меня есть следующие 2 класса: Прямоугольник (Который построен из другого класса, но в настоящее время нас это не касается)
а также сетка.
со следующими конструкторами:

(Конструктор точек для частных прямоугольников topLeft и bottomRight):

Point::Point(int x, int y) {this->x = x; this->y = y;}

(Конструктор и класс прямоугольника)

class Rectangle
{
public:
Rectangle(int l, int u, int w, int h, int color);
//int getColor() const;
//void setColor(int color);
//bool contains(const Point &p) const;
//void print() const;
private:
const Point topLeft, bottomRight;
int color;
};

Rectangle::Rectangle(int l, int u, int w, int h, int color) :
topLeft(l, u),
bottomRight(l + w, u + h)
{ this->color = color; }

(Grid Constructor and Class) (допустим, я не хочу инициализировать значения Rectangle в Grid, просто выделю их в памяти)

class Grid
{
public:
Grid(int tileW, int tileH, int width, int height, int color);
//~Grid();
//Rectangle& getRectAt(const Point &p);
//void print() const;
private:
int count;
Rectangle **recs;
};

Grid::Grid(int tileW, int tileH, int width, int height, int color)
{
int index, index_c=0;
recs = new Rectangle *[width];

for (int index = 0; index < width; index++)
{
recs[index] = new Rectangle[index];
}

}

Итак, как вы можете понять, у меня есть проблема в конструкторе сетки со следующей ошибкой
(Ошибка 1, ошибка C2512: «Прямоугольник»: нет подходящего конструктора по умолчанию.)
но я просто не могу понять, почему это не сработает, мне предложили выделить двойной указатель Recs как одномерный массив (массив с длиной Width * Height), но что если Recs был 4-мерным массивом? Как вы могли бы выровнять его правильно, а затем индексировать вокруг 4-мерного массива, не испытывая головной боли при расчете индекса каждой ячейки в массиве.

другое дело, мы знаем, что если бы это было int **, а не recs **, это работало бы отлично

int **foo;
int height,width;
foo = new int* (height);
for (int index = 0; index<height; ++index)
foo[index] = new int[width];

поэтому я просто упускаю способ создания n-мерных массивов в C ++.

2

Решение

Линия recs[index] = new Rectangle[index]; пытается вызвать конструктор Rectangle по умолчанию index раз. Если вы хотите создать несколько объектов одновременно, вы, вероятно, захотите добавить ctor по умолчанию и простой метод установки в ваш класс Rectangle.

class Rectangle
{
public:
Rectangle(int l, int u, int w, int h, int color);
Rectangle() = default;
void set(int l, int u, int w, int h, int color);
private:
const Point topLeft, bottomRight;
int color;
};

Затем в цикле создания:

for (int index_w = 0; index_w < width; index_w++)
{
recs[index_w] = new Rectangle[height]; //see note below
for (int index_h = 0; index_h < height; index_h++)
recs[index_w][index_h].set(/* some math with width, height and loop variables*/, color);
}

Заметка: Я изменился index в heightпотому что вы хотите создать 2D массив, поэтому общий размер сетки будет высота * ширина. При создании длины индекса вместо этого вы бы создали треугольную сетку (и более того, первая итерация цикла будет recs[0] = new Rectangle[0] — массив нулевой длины).

Как упомянул пользователь Macro A, рассмотрите возможность использования std::vector<Rectangle> вместо необработанных указателей (2D-массив будет std::vector<std::vector<Rectangle>>)

Кроме того, рассмотрите возможность изменения вашего дизайна, потому что в настоящее время вы создаете сетку H x W объектов Rectangle, где все точки (кроме первой / последней) дублируются на смежных прямоугольниках (каждая точка — это верхний левый угол одного прямоугольника, верхний правый угол другой, левый нижний …).

Я предлагаю класс Grid, который содержит двумерный массив целых и имеет метод Rectangle getRectangle(int x, int y) который вернул бы соответствующий набор из 2 баллов. Модификация такого класса Grid будет намного проще, и вам не придется перебирать все прямоугольники, только целые

1

Другие решения

Вы могли бы использовать размещение нового : вы изначально резервируете достаточно места для хранения массива объектов, а затем индивидуально создаете их каждый на своем месте.

В вашем коде это может стать (более или менее):

for (int index = 0; index < width; index++)
{
// first simple allocation for the array
recs[index] = (Rectangle *) malloc(sizeof(Rectangle) * height);
for (int j=0; j<height; j++) {
// individually build each rectangle in place
new(&recs[index][j]) Rectangle(index*tileW, j*tileH, tileW, tileH, color);
}
}

Это предназначено для того, чтобы делать именно то, что вам нужно: создавать массивы конструируемых объектов по умолчанию.

Несвязанный: поскольку вы используете сырые указатели и выделенные массивы, не забудьте правильно все освободить. С помощью std::vectorможет спасти тебя от этого …

0

Вы получаете ошибку C2512, потому что у вас нет конструктора по умолчанию в Rectangle, Единственный конструктор, который у вас есть Rectangle параметризован, в то время как конструктор по умолчанию требует, чтобы он вызывался без дополнительных аргументов.

Глядя на линию recs[index] = new Rectangle[index];вы видите, что нет никаких аргументов для 5 параметров, которые принимает конструктор. Для компиляции этой строки вам нужно создать конструктор по умолчанию либо с новым конструктором с подписью Rectangle() или аргументы по умолчанию для параметров в вашем параметризованном конструкторе, например Rectangle(int l = 0, int u = 0, int w = 0, int h = 0, int color = 0);,

Если вы хотите выделить память, вы должны создать конструктор по умолчанию и использовать std::vector<Rectangle> который вы инициализируете с размером. Затем вы можете позже заменить объекты с помощью конструктора копирования, как показано в этом примере: http://ideone.com/KnUBPQ

Что касается создания n-мерного массива, вы явно ограничили его двумерным массивом с помощью Rectangle а также Point классы. Если массив будет n-мерным, ваши точки тоже должны быть n-мерными:

template<int dimensions>
class Point
{
std::array<int, dimensions> coords;

...
};

или же

class Point
{
std::vector<int> coords;

...
};
0
По вопросам рекламы [email protected]