0

Given a struct like

struct Square
{
  Square(Color p_color): color_(p_color) {}
  Color color_;
 };

how can i declare a two dimensional array and later initialize it. For example,

typedef Square (&Square8x8)[8][8];

Square8x8 initSquares()
{
    Square board[ROWS][COLS]; //declare the array

    for(int row=0;row<ROWS;row++)
            for(int col=0;col<COLS;col++)
            {
                    if(col%2 == 0)
                            board[row][col]= Square(WHITE); //actual initlization
                    else
                            board[row][col] = Square(BLACK);
            }
    return board;

 }
4
  • 2
    You can't. A constructor must be called for each element in the array. Commented May 25, 2013 at 12:24
  • 1
    The whole point of a constructor is that you cannot bypass it. Commented May 25, 2013 at 12:26
  • If preallocating memory is your requirement, then you should look up placement new and there too eliding constructor isn't an option but you can handle the memory (de)allocation. Commented May 25, 2013 at 12:49
  • Since you are actually allocating ROWS*COLS Square elements they need to be properly constructed. Do you want to use your existing constructor instead of a default constructor? Commented May 25, 2013 at 12:51

4 Answers 4

4

You misunderstand the point of a constructor, which is to ensure an object is always initialized and valid during its entire lifecycle. Thus the invocation of a constructor cannot be in any way delayed or postponed.

It's a typical XY-problem though - you're asking for help with an intended solution, not a problem. The real problem is that you don't want to postpone the constructor, but initialize it later on. Construction and initialization are related subjects, but not identical.

The best solution is to give your class a setColor or initialize function, separate from the constructor. An alternative solution (which is closer to your question) is to declare the array not as objects, but as pointers, and then really instantiate the object later on with new Square(WHITE). I'd go for the first though, the second requires a lot more lifecycle control with explicit deletion.

Sign up to request clarification or add additional context in comments.

3 Comments

+1, clearly an XY problem. Another solution is to have an array of boost::optional or std::optional objects.
+1 for the STL additions, my answer is based on 'raw' C++, but using STL containers will simplify lifecycle management.
The original problem seems to be stackoverflow.com/questions/16749103/…
1

You need a default constructor for Square which is able to call without parameters. For example:

struct Square
{
  Square() {}  // <------------------------- For example
  Square(Color p_color): color_(p_color) {}
  Color color_;
};

Otherwise, you should use pointer to Square and new them later. For example:

struct Square
{
  Square(Color p_color): color_(p_color) {}
  Color color_;
};
const int ROWS = 8;
const int COLS = 8;

In this case, you should use pointers:

std::unique_ptr<Square> board[ROWS][COLS];

for (int i=0; i<ROWS; i++)
    for (int j=0; j<COLS; j++)
        board[i][j] = std::unique_ptr<Square>(new Square(RED));

or (for bare pointers)

Square* board[ROWS][COLS];

for (int i=0; i<ROWS; i++)
    for (int j=0; j<COLS; j++)
        board[i][j] = new Square(RED);

....
// Be careful, you should delete them all 

7 Comments

But i really do not want user to construct an empty Square.. Is there a way to do it without default constructor?
So something like Square * board[ROWS][COLS];
OP is asking how to create an array of objects without calling a constructor, not how to implement a default constructor.
If i have to return Square * board[ROWS][COLS] from a function, what should the function signature look like?
@Jimm: I've put it. check it out.
|
1

In case you don't want to use a default constructor you can use the constructor you already have.

This solution uses std::vector, which I also recommend you use.

std::vector<Square> myVector( ROWS*COLS, Square(WHITE) );

this will create an array of ROWS * COLS elements, each initialized to the value of Square(WHITE).

You could create a Board class, which uses such a vector inside and offers functionalities such as initializing a board of arbitrary size and indexing a Square in the linear vector based on Row and Column information.

You can also do:

Square board[2][2] = {Square(WHITE), Square(WHITE), Square(WHITE), Square(WHITE) };

but it doesn't really scale well.

Comments

0

Create an array of (smart) pointers instead of an array. One purpose of pointers is so objects can be initialized later.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.