2

我一直在 StackOverlow 周围寻找答案,但我没有找到答案,所以我希望这不是这里任何帖子的重复。

所以,我有下一个问题。
假设我有接下来的 2 个类:Rectangle(它是从另一个类构建的,但它目前不关心我们)和Grid。他们跟随构造函数:

(矩形私有 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; }

(网格构造函数和类)(假设我不想在网格中初始化 Rectangle 的值,只是将它们分配到内存中)

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

}

所以,正如你所理解的,我在 Grid 构造函数中遇到了以下错误
(错误 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];

所以我只是一直想念在 C++ 中做 n 维数组的方式。

4

3 回答 3

1

该行recs[index] = new Rectangle[index];尝试调用 Rectangle 的默认构造函数index时间。如果您想一次创建多个对象,您可能需要将默认 ctor 和简单的 setter 方法添加到 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);
}

注意:我改成indexheight,因为要创建二维数组,所以网格的总大小是高*宽。在创建索引长度时,您将改为创建三角形网格(此外,第一次循环迭代将是recs[0] = new Rectangle[0]- 一个零长度数组)。

正如用户宏 A 所提到的,考虑使用std::vector<Rectangle>而不是原始指针(二维数组将是std::vector<std::vector<Rectangle>>

另外,请考虑更改您的设计,因为目前您正在创建一个矩形对象的网格 H x W,其中所有点(第一个/最后一个除外)在相邻矩形之间重复(每个点是一个矩形的左上角,右上角另一个角落,左下角...)。

我提出了一个 Grid 类,它包含 2D 整数数组,并有一个方法Rectangle getRectangle(int x, int y)可以返回适当的 2 点集。修改这样的 Grid 类会容易得多,而且您不必遍历所有 Rectangle,只需 ints

于 2016-11-25T10:35:37.547 回答
0

您可以使用放置 new:您最初保留足够的位置来存储对象数组,然后分别在自己的位置构建它们。

在您的代码中,它可能会变成(或多或少):

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::vectors 可以使您免于...

于 2016-11-25T11:24:42.097 回答
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 维数组,你已经明确地将它限制为一个二维数组,其中包含你的RectanglePoint类。如果数组是 n 维的,那么您的点也需要是 n 维的:

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

    ...
};

或者

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

    ...
};
于 2016-11-25T16:00:57.560 回答