【问题标题】:C++ matrix of classes (pointer of pointers)类的 C++ 矩阵(指针的指针)
【发布时间】:2017-04-05 07:27:13
【问题描述】:

所以我在 C++ 中遇到了一些问题(我的第一个编程语言是 C)。

假设我有以下课程:

2个标题(矩形和网格,假设点类很好,另一个假设是我们目前不需要打印函数)

Grid.h

#ifndef GRID_H
#define GRID_H
#ifndef RECT_H
#include "Rectangle.h"

#endif

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

矩形.h

#ifndef RECT_H
#define RECT_H
#ifndef POINT_H
#include "Point.h"
#endif

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

#endif

和 2 个 cpp:

矩形.cpp

#include "Rectangle.h"

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

int Rectangle::getColor() const
{
    return this->color;
}

void Rectangle::setColor(int color)
{
    this->color = color;
}

bool Rectangle::contains(const Point &p) const
{
    return (this->topLeft.getX < p.getX && p.getX < this->bottomRight.getX
        && this->bottomRight.getY < p.getY && p.getY < this->bottomRight.getY);
}

void Rectangle::print() const
{
    /**/
}

Grid.cpp

#include "Grid.h"

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

}

(假设我们不需要其他 Grid 函数并且构造函数没有完成)。
现在我要做的是,在 Grid.cpp 构造函数中,我正在尝试 动态分配数组的数组,但我只是无法理解 cpp 中类的内存分配背后的逻辑。 如果有人能向我解释 cpp 中的“新”功能如何在类和 n 维数组(类和一般情况下)上发挥作用,我将不胜感激。

希望你能理解我在这里遇到的问题。

提前致谢。

【问题讨论】:

  • 不要在 c++ 中使用原始指针和new / delete。请改用容器和智能指针。
  • 关于:“假设是我们目前不需要打印功能”而不是做出假设,删除代码并证明它是正确的。您不仅会因为自己是对的而感到满足,而且您会拥有更小的寻找错误的表面积,并且更接近这个问题成为主题所需的minimal reproducible example
  • 不是完全重复,而是一个更好的方向:Initializing a two dimensional std::vector

标签: c++ class new-operator n-dimensional


【解决方案1】:

如 cmets 中所述,它更好/更易于使用一些容器模板,例如:

                vector< Rectangle >     recs_1D;
        vector< vector< Rectangle > >   recs_2D;
vector< vector< vector< Rectangle > > > recs_3D;

其中vector&lt;T&gt; 是自分配一维数组的任何容器类模板,例如std::vector。请确保对于嵌套模板,在 &lt;&gt; 之前有空格,否则某些编译器可能会抛出语法错误。

您甚至可以像这样创建自己的容器:

然后查找List_static 模板(有完整代码)它的静态(为简单起见没有动态分配),但您可以将其用作模板代码来添加动态分配。

如果您坚持使用new,delete(在某些情况下比在第 3 方模板代码上中继更快/更好/更安全/必要),就像这样(直接写在这里,因此它可能包含拼写错误和按顺序为了让它简单快速你需要定义没有操作数的矩形构造函数Rectangle::Rectangle(){} !!!):

// some variables for 2D grid
int xs=0,ys=0;                // size of 2D grid [rectangles]
Rectangle **rec=NULL;

// allocation
xs=100; ys=50;                // wanted size
rec=new Rectangle*[xs];       // pointers for each column
rec[0]=new Rectangle[xs*ys];  // whole grid xs*yus rectangles (and also the first column)
for (int x=1;x<xs;x++)        // set all pointers to point to their column
 rec[x]=rec[x-1]+ys;

// now you can use rec[x][y]
rec[3][7]=Rectangle(3,7,1,1,55);

// releasing of memory
if (rec)
 {
 if (rec[0]) delete[] rec[0]; // release the grid
 delete[] rec;                // release pointers
 }
xs=0; ys=0; rec=NULL;

如果您不能使用没有操作数的构造函数(出于任何原因),那么您需要将 rec[0]new/delete[] 更改为嵌套在 (x,y) 循环中的 2 个并使用 rec[x][y] 代替,这会慢得多并且破坏堆和 C++ 引擎内存管理。

您可以在任何维度上使用它...只需将 * 添加到指针,为每个轴添加分辨率变量和另一个 for 循环以及一个 new,delete[]...

【讨论】:

    【解决方案2】:
    Grid::Grid(int tileW, int tileH, int width, int height, int color)  // האם ניתן להניח את תקינות הקלט ? 
    {
      int i ,j ; 
      i=0;
      count=height*width;
      recs=new Rectangle* [count];
     
      for(i=0;i<count;i++)
       for(j=0;j<width;j++)
        {
            recs[i+j]=new Rectangle (tileW*j,tileH*i,tileW,1,tileH);
        }
    
    }
    

    您需要使用 1 个长数组并像二维一样对其进行寻址。

    【讨论】:

    • 是的,但是如果我们谈论的是 n 维数组,您将无法跟进您的索引,所以我宁愿找到如何将其拆分为数组数组的解决方案。当然是其中之一。
    • 我不确定没有默认构造函数是否可行
    猜你喜欢
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    相关资源
    最近更新 更多