C ++私有类动态n维数组

时间:2016-11-25 10:02:19

标签: c++ class dynamic-memory-allocation n-dimensional

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

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

(Rectangle private topLeft和bottomRight的Point构造函数):

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

(Rectangle Constructor and Class)

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中初始化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:&#39;矩形&#39;:没有合适的默认构造函数。)
但是我不明白为什么它不起作用,我曾建议将Recs双指针分配为1维数组(长度为Width * Height的数组)但是如果Recs是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维数组的方法。

3 个答案:

答案 0 :(得分: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);
}

注意:我已将index更改为height,因为您要创建2D数组,因此总网格大小为height * width。在创建索引长度时,您将创建三角形网格(而且更多,第一个循环迭代将是recs[0] = new Rectangle[0] - 零长度数组。)

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

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

我提出了一个Grid类,它包含两个int数组,并且有一个方法Rectangle getRectangle(int x, int y),它将返回适当的2个点集。对这样的网格类进行修改会更容易,并且你不必遍历所有矩形,只需要整理

答案 1 :(得分:0)

您可以使用贴装新:您最初预留足够的位置来存储对象数组,然后分别在各自的位置单独构建它们。

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

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 s可以帮助您避免......

答案 2 :(得分: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;

    ...
};