2D-Array with Polymorphy

I wanna create a field for a little game. The field consists of the followed classes:

Floor
Wall
Door

All 3 of them are derived classes of the abstract class Tile. With it I wanna create the field with 7x7 per Polymorphism. The field should be on the heap so it cannot be vanished by the compiler.

 ``1234`` ``````const int width = 7; const int height = 7; Tile*** field;``````

How can I create the field?

rumpfi88
I don't really understand what you are trying to do. And why is data on the stack
 vanished by the compiler
?
If your field will never change size during a game it might be easier to declare it like this:

 `` `` ``Tile field = new Tile[7][7];``

Tile is a abstract class, you can't create the field like you did, Galik.

But if you read it from a config-file with ifstream, how to create the field dynamicly?
Last edited on
Good point, I should have made an array of pointers.

Well:

Tile* is Tile pointer or array of Tile.

Tile** is array of Tile pointer

Tile*** is array of array of Tile*

So we are dealing with arrays of arrays. So you need to allocate an array and then visit each element of that array to allocate another array to each one:

 ``12345678910111213141516171819202122232425`` `````` const size_t x_size = 7; const size_t y_size = 7; // Declare an 'Tile***' (array of array of Tile*) Tile*** field; // Allocate your 'Tile***' field = new Tile**[x_size]; // Every element is a 'Tile**' (array of Tile*) // Visit every 'Tile**' element for(size_t x(0); x < x_size; ++x) { // Allocate a 'Tile*' to each 'Tile**' element field[x] = new Tile*[y_size]; // Every element of this array is a 'Tile*' (array of Tile) // Visit every 'Tile*' element for(size_t y(0); y < y_size; ++y) { // Allocate a Tile to every Tile* element field[x][y] = new Tile; } } ``````
Tile is a abstract class, you can't create an object of Tile, but of the derived classes.

I already came with the idea of using this:

 `` `` ``std::vector> field;``

now a double for-loop

 ``1234567891011`` ``````for(int y = 0; y < height; y+) { field.push_back( std::vector() ); for(int x = 0; x < width; x++) { // if Tile from config == Wall Tile* tile = new Wall(...); field[y].push_back(tile); .... } }``````

This method works, I came with it while I was in University right now. But thanks to all.
closed account (1yR4jE8b)
I'm working on something very similar, so I think I could help you

I'd like to repeat what someone else already said:

 vanished by the compiler

lol wut?

Also, I am absolutely disgusted at the sight of a `Object***`, do you really want to be known as a three star programmer ;-P ?

http://www.c2.com/cgi/wiki?ThreeStarProgrammer

Before you know it you'll be knowing nested #if #elsif macros and no one but you will be able to maintain your code :P.

May I suggest wrapping your "Field" in a class as well, and only using an array of Tile* of size m * n, and accessing your array elements using an overload `operator()`. It will make things MUCH MUCH easier in the long run, there are also less pointer chases so it is more efficient.

Something like this:

Field.h
 ``123456789101112131415161718192021222324252627`` ``````#ifndef _FIELD_H_ #define _FIELD_H_ #include "Tile.h" class Field { public: typedef unsigned int size_type; Field(size_type rows, size_type cols); Field(const Field& other); virtual ~Field(); Field& operator=(const Field& other); Tile* operator()(size_type row, size_type col); const Tile* operator()(size_type row, size_type col) const; private: Tile** grid; size_type numRows, numCols; }; #endif /* _FIELD_H_ */ ``````

Field.cpp
 ``123456789101112131415161718192021222324252627282930313233343536373839`` ``````#include "Field.h" Field::Field(size_type rows, size_type cols) : grid(new Tile*[numRows * numCols]), numRows(rows), numCols(cols) { //additional implementation ommited } Field::Field(const Field& other) : grid(new Tile*[other.numRows * other.numCols]), numRows(other.numRows), numCols(other.numCols) { //additional implementation ommited } Field::~Field() { //additional implementation ommited } Field& Field::operator=(const Field& other) { if(this != &other) { //additional implementation ommited } return *this; } /** This is the important bit right here **/ Tile* Field::operator ()(size_type row, size_type col) { return grid[row * numCols + col]; } const Tile* Field::operator ()(size_type row, size_type col) const { return grid[row * numCols + col]; }``````

Last edited on
Topic archived. No new replies allowed.