0

I wrote the following code for creating a chessboard using 2D Arrays in C++ :

#include <iostream>
#include <iomanip>
#include <array>
using namespace std;

Here is the ChessBoardArray class:

class ChessBoardArray
{

protected:
    class Row
    {
        public:
            Row(ChessBoardArray &a, int i): cba(a), row(i){}
            int & operator[] (int i) const
            {
                return cba.select(row, i);
            }
        private:
            ChessBoardArray &cba;
            int row;
    };

    class ConstRow
    {
        public:
            ConstRow(const ChessBoardArray &a, int i): cba(a), row(i){}
            int operator[] (int i) const
            {
                return cba.select(row, i);
            }
        private:
            const ChessBoardArray &cba;
            int row;
    };

    unsigned int my_size;
    int my_base;
    int *data;

The loc function is for finding the location of an element. It corresponds the elements of the 2D array to the corresponding position.

    unsigned int loc(int i, int j) const throw(out_of_range)
    {
        int di = i - my_base, dj = j - my_base;
        if(di < 0 || di >= my_size || dj < 0 || dj >= my_size) throw out_of_range("invalid index");
        return di * my_size + dj;
    }

public:
    ChessBoardArray(unsigned size = 0, unsigned base = 0)
    {
        my_size = size;
        my_base = base;
        data = new int[my_size * my_size];
    }

    ChessBoardArray(const ChessBoardArray &a)
    {
        my_size = a.my_size;
        my_base = a.my_base;
        data = new int[my_size * my_size];

        for(int i = 0; i < my_size*my_size; i++) data[i] = a.data[i];
    }

    ~ChessBoardArray()
    {
        delete [] data;
    }

    ChessBoardArray & operator= (const ChessBoardArray &a)
    {
        this -> ~ChessBoardArray();

        my_size = a.my_size;
        my_base = a.my_base;
        data = new int[my_size * my_size];

        for(int i = 0; i < my_size*my_size; i++) data[i] = a.data[i];

        return *this;
    }

    int & select(int i, int j)
    {
        return data[loc(i, j)];
    }
    int select(int i, int j) const
    {
        return data[loc(i, j)];
    }    

    const Row operator[] (int i) 
    {
        return Row(*this, i);
    }
    const ConstRow operator[] (int i) const
    {
        return ConstRow(*this, i);
    }

    friend ostream& operator<< (ostream &out, const ChessBoardArray &a)
    {
        for(int i = a.my_base; i <= a.my_size; i++)
        {
            for(int j = a.my_base; j <= a.my_size; j++)
            {
                out << setw(4) << a.data[a.loc(i, j)];
            }
            out << endl;
        }
        return out;
    }

};

The condition for a number to be in a white box is i%2 == j%2. Where should i add the condition in my code? I tried putting it inside the loc function but it got me some errors.

angeloskar
  • 19
  • 1
  • you're not using 2D arrays, `data` is 1D array – Iłya Bursov May 14 '22 at 19:51
  • Please isolate the task into a [mcve]. Also, "it got me some errors" is not something you could search online in order to find solutions. Please read [ask] and perhaps take the [tour]. – Ulrich Eckhardt May 14 '22 at 19:52
  • Correct, yes my bad. When i said 2d i was referring to the output where it looks like a 2darray - matrix – angeloskar May 14 '22 at 19:54
  • 1
    @angeloskar Why not simply use `class ChessBoardArray { private: std::vector data; ...};` and spare having to do silly things like this: `this->~ChessBoardArray();`? What's the reason for calling the destructor explicitly? This should not be done in the context where you are doing this. Calling the destructor explicitly would be done in the context of using `placement-new`, but none of your code does this. – PaulMcKenzie May 14 '22 at 19:57
  • 1
    And given all of that, your `operator=` could simply be: `{ ChessBoardArray temp(a); std::swap(my_size, temp.my_size); std::swap(my_base, temp.my_base); std::swap(data, temp.data); return *this; }`. You can see how this works, since if you note, your `operator=` and copy constructor are almost identical. Thus using the copy constructor to create a temporary copy and swapping everything is much less error prone and safer than what you're doing now. This is called the [copy/swap idiom](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) – PaulMcKenzie May 14 '22 at 20:03
  • Why `Row` and `ConstRow` instead of `const Row`? – Sebastian May 15 '22 at 04:32
  • Could you better describe, what you want to do? Generate the indices of white fields? As 1D or 2D number? Or just determine the color of a given field. Is the color dependent on `base`? What happens with odd `sizes`? Which corner should keep its color, when increasing the size? – Sebastian May 15 '22 at 04:38

0 Answers0