Initializing an array of two-dimensional objects in C ++

I know this was asked before (or some similar options), however I cannot get it to work.

I am trying to create a board game consisting of a board filled with squares. I am trying to simulate my board as a 2d array of square objects. The board can be created with any width or height, and these parameters are passed through the constructor. Here is the code I'm working with:

Board.h

 #ifndef BOARD_H #define BOARD_H #include "Square.h" class Board{ public: Board(int w, int h); private: Square **squares; const int width; const int height; }; #endif 

Board.cpp

 #include "Board.h" Board::Board(int w, int h):width(w), height(h) { squares = new Square*[width]; for (int i = 0; i < width; i++) { squares[i] = new Square[height]; } } 

However, when I try to compile this, I get an error message that seems to indicate that squares[i] = new Square[height] trying to call the default constructor for the Square object (which I don't want to exist and not call in in this case).

 Board.cpp: In constructor 'Board::Board(int, int)': Board.cpp:7:33: error: no matching function for call to 'Square::Square()' squares[i] = new Square[height]; 

Any ideas? Is this possible in C ++?

+2
c ++ arrays
source share
3 answers

Your code is equivalent to this:

 struct Foo { Foo(int){} // no default constructor // Foo() = default; /* uncomment this and it will work */ }; int main() { Foo* pFoo = new Foo[10]; // need a default ctor delete[] pFoo; } 

The problem is that in rhs Foo* pFoo = new Foo[10]; you allocate memory , and also create 10 Foo objects . The compiler does not know how to do the latter (creating objects), since you do not provide a default constructor. For this code to work as it is, you need to specify all arguments for the non-default ctor of each object, for example:

 Foo* pFoo = new Foo[10]{1,2,3,4,5,6,7,8,9,0}; // this will work 

A better alternative is to use std::vector . If you are wondering why the latter works without the need for objects that do not have a default constructor, this is because it uses the new location and initializes the elements on demand.

Here you can see how to do this with the new placement.

EDIT

The code

 Foo* pFoo = new Foo[10]{1,2,3,4,5,6,7,8,9,0}; 

compiles in gcc, but clang cannot compile it (with the -std=c++11 flag). The next question is here .

+4
source share

You asked him to create a buffer of n squares. He tried to do this and failed because he could not build them.

If you need memory for squares n , use new std::aligned_storage_t<sizeof(Square),alignof(Square)>[Count] . Then use the new layout to create each item in turn.

But this is a stupid idea. It is complex, opaque and error prone.

In short, Stop memory management manually .

vector solves this problem for you.

Create vector of squares vector. Or create a flat vector and do the math to find the index. It is an internally configured bit of memory and uses the new location to build on demand, so you don’t need to write this dangerous complex code yourself.

Vectors allow you to dynamically and efficiently generate them, and beautifully replace manually managed arrays. But you need to grow them from the smallest to the greatest element. If you don't want this, use unique ptrs vectors for squares and highlight as needed (or, std::experimental::optional<Square> if you use C ++ 17 / 1z compilers).

Or just use a map from pair<int,int> to Square and make it sparse. Note that you will use emplace and not call [] unless you want the default square for the square. Again, you can use unique ptrs for Square instead of squares.

There are many options.

Also consider whether Square ctor is the default value: regular types are awesome.

+2
source share

As another mentioned answer, you can create a flat vector and do some simple arithmetic to calculate the index.

 int main() { // dimensions of the board int width = 100; int height = 102; // some coordinates on the board int x = 10; int y = 32; // allocate memory for every element on the board (10200 elements) int * board = new int[width * height]; // access element (x, y) of the board int val = board[y*width + x] // don't forget to delete dynamic memory! delete [] board; } 

No two different coordinates will have the same index.

+1
source share

All Articles