Itay.V
Itay.V

Reputation: 161

C++ matrix of classes (pointer of pointers)

So I've encountered some problem in C++ (my first programming language was C).

Let's say I have the following classes:

2 headers (rectangle and grid, assume that point class is fine and another assumption is that we don't need print functions currently)

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

Rect.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

and the 2 cpp's:

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

}

(assume that we don't need the other Grid functions and the constructor isn't finished).
Now what I'm trying to do is this, in Grid.cpp constructor, I'm trying to dynamically allocate the Array of Arrays but I just can't understand the logic behind the memory allocation of classes in cpp. I would appreciate if some one could explain me how the 'new' functions in cpp on classes and on n-dimensional arrays (of classes and in general).

I hope you understood the problem that I encounter here.

Thanks in advance.

Upvotes: 0

Views: 854

Answers (2)

benz
benz

Reputation: 201

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

}

You need to use 1 long array and address it like 2 dimensional.

Upvotes: 0

Spektre
Spektre

Reputation: 51845

as mentioned in the comments its better / easier to use some container template like:

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

Where vector<T> is any container class template of self allocating 1D array like std::vector. Just be sure that for nested templates you got space after < and before > otherwise some compilers might throw an syntax error.

You can even create your own container like this see:

And look for List_static template (there is full code) its static (so no dynamic allocations for simplicity) but you can use it as a template code to add the dynamic allocations to it.

How ever if you insist on using new,delete (which is in some cases faster/better/safer/necessary) than relay on 3th party template code its like this (writing directly in here so it might contain typos and In order to make it simple and fast You need to have defined rectangle constructor without operands 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;

In case you can not use constructor without operands (for any reason) then you need to change the new/delete[] of rec[0] to 2 nested for (x,y) loops and use rec[x][y] instead which would be much slower and trashing the heap and C++ engine memory management.

You can use this in any dimensionality... Just add * to pointer, add resolution variable and another for loop for each axis and also one new,delete[]...

Upvotes: 0

Related Questions