Malfist
Malfist

Reputation: 31815

Creating a 2D array on construction with a variable length

How can a setup a class that I can have a private 2D array that's size is determined by the variables passed in via the constructor?

I've tried this:

class World {
    private:
        const int WIDTH;
        const int HEIGHT;
        bool map[][];
    public:
        World(const int MAX_X, const int MAX_Y) : WIDTH(MAX_X), HEIGHT(MAX_Y) {
            map = new bool[WIDTH][HEIGHT];
        }
};

But I get a bunch of errors about how declaration of ‘map’ as multidimensional array must have bounds for all dimensions except the first and array size in operator new must be constant even though it is.

I've also tried it this way but it didn't work either:

class World {
    private:
        const int WIDTH;
        const int HEIGHT;
        bool map[WIDTH][HEIGHT];
    public:
        World(const int MAX_X, const int MAX_Y) : WIDTH(MAX_X), HEIGHT(MAX_Y) {
            //map = new bool[WIDTH][HEIGHT];
        }
};

I get a invalid use of non-static data member ‘World::WIDTH’ on the const int WIDTH line and a quite useless error: from this location on the map declaration line.

What am I doing wrong?

Edit: I'd prefer to avoid using vectors since I haven't "learned" them yet in this class. (by learned I mean I know how to use them but the professor hasn't discussed them and doesn't like us using outside knowledge)

Upvotes: 0

Views: 113

Answers (2)

Aesthete
Aesthete

Reputation: 18858

You could use a vector.

class World
{
   typedef std::vector<bool> Tiles;
   typedef std::vector<Tiles> WorldMap;

   World(unsigned int width, unsigned int height)
   {
     for (unsigned int i = 0; i < width; i++)
     {
         m_map.push_back(Tiles(height));
     }
   }

private:
   WorldMap m_map;      
};

Or you could use templates, if you know the world size at compile time.

template <unsigned int Width, unsigned int Height>
class World
{
private:
  bool m_map[Width][Height];
};

Or you could use raw pointers, since a 2d array is really just an array of pointers to arrays.

class World
{
   // Make sure you free this memory.
   World(unsigned int width, unsigned int height)
   {
     m_map = new bool*[width];
     for(unsigned int i = 0; i < height; ++i)
     {
        m_map[i] = new bool[width];
     }
   }

private:
   bool** m_map;
};

I suggest using one of the first two options.

Upvotes: 1

PaulMcKenzie
PaulMcKenzie

Reputation: 35455

Arrays must have their sizes determined at compile-time, not run time.

You should choose a different container if you want run-time sizing. Possibly:

 - std::vector<bool>  // and then simulate a 2d array using indexing 
 - std::vector<std::vector<bool>> // if you insist on using [][] syntax

Upvotes: 0

Related Questions