0

I have a Vector2D struct that I am using to hold a 2D array of Tile objects and Chunk objects:

template<typename T>
struct Vector2D
{
    Vector2D() = delete;
    Vector2D(U32 sizeX, U32 sizeY) : _size1{ sizeX }, _size2{ sizeY }
    {
        _array = new T * [_size1];

        for (U32 i = 0; i < _size1; i++)
        {
            _array[i] = new T[_size2];
        }
    }

    ~Vector2D()
    {
        for (U32 i = 0; i < _size1; i++)
        {
            delete[] _array[i];
        }

        delete[] _array;
    }

    T& operator[](const Vector2& v) { assert(v.x < _size1&& v.y < _size2 && "vector out of bounds"); return _array[(U32)v.x][(U32)v.y]; }
    const T& operator[](const Vector2& v) const { assert(v.x < _size1&& v.y < _size2 && "vector out of bounds"); return _array[(U32)v.x][(U32)v.y]; }

    T*& operator[](const U32& i) { assert(i < _size1 && "index out of bounds"); return _array[i]; }
    const T*& operator[](const U32& i) const { assert(i < _size1 && "index out of bounds"); return _array[i]; }

    U32& sizeX() { return _size1; }
    U32& sizeY() { return _size2; }
    U64& size() { return (U64)_size1 * _size2; }

private:
    T** _array;
    U32 _size1;
    U32 _size2;
};

since it has to default constructor, I have to construct it an a member initialization list here:

World::World(I32 seed, WorldSize size) : _seed{ seed }, _size{size},
    CHUNKS_X{ (U16)(_size / CHUNK_SIZE) }, CHUNKS_Y{ (U16)(CHUNKS_X / WORLD_RATIO) },
    _tiles(_size, _size / WORLD_RATIO), _chunks(CHUNKS_X, CHUNKS_Y)
{
    Chunk::world = this;
    Player::world = this;

    WorldGen::GenerateWorld(_seed, _size, _tiles);

    player = new Player(Vector2(_size / 2.f + 0.5f, _size / WORLD_RATIO / 2.f + 0.5f));

    for (U16 x = 0; x < CHUNKS_X; x++)
    {
        for (U16 y = 0; y < CHUNKS_Y; y++)
        {
            _chunks[x][y] = new Chunk(Vector2(x, y));
        }
    }

    InitWorldView();
}

this all works fine for the 2D array of Tiles, but when I construct the Chunks 2D array, it doesn't save the _size1 & 2 variables, and thus I get an assertion error when I try to access it:

Showing that the values for the parameters are not zero, and the final struct still has zeros for them

  • Can you show the declaration of `World`? Specifically, what is the order of the member variables in it? Does it match the order in the initializer list? – Retired Ninja Jun 04 '21 at 03:09
  • 1
    `int main() { Vector2D v1(1,1); Vector2D v2 = v1; }` -- double deletion error. Fix this first by either providing a copy constructor and assignment operator, or make those functions `delete`d so that copies cannot be made. – PaulMcKenzie Jun 04 '21 at 03:12
  • Please edit the original post with the updated code. – PaulMcKenzie Jun 04 '21 at 03:15
  • @Retired Ninja, no clue that effected it, thanks a lot that fixed it – Zachary Peterson Jun 04 '21 at 03:16
  • Also: `U32& sizeX() { return _size1; }` -- Are you really sure you want to return a reference here? Why not just return the `int`? – PaulMcKenzie Jun 04 '21 at 03:17
  • Member variables are initialized in the order declared, regardless of the order of the initializer list. That means the size calculated for `CHUNKS_X` and `CHUNKS_Y` happens after `_chunks` is initialized. – Retired Ninja Jun 04 '21 at 03:18
  • 1
    Yes, I now understand how that works, and thanks @PaulMckenzie for pointing out things that could cause problems down the road, I deleted the copy and assignment, and Those methods are suppost to be const references, I know it does really matter since it's just 4 bytes, but I'm getting into the habit of returning const references – Zachary Peterson Jun 04 '21 at 03:24

0 Answers0