simple inheritance question

N

Numeron

This is part of my first ever largish project, a tile based game. I
havent got a lot of experience with c++ so be nice ;)

this is all within Tile.h, a lot has been taken out or simplified for
the sake of...er simplicity lol.

class Tile{
private:
int locationX;
int locationY;
public:
Tile(int inLocX, int inLocY){
setLocX(inLocX);
setLocY(inLocY); }
void setLocX(int inLocX){ locationX = inLocX; }
void setLocY(int inLocY){ locationY = inLocY; }
int getLocX(){ return locationX; }
int getLocY(){ return locationY; }
}//end of Tile class

class FloorTile : public Tile{
private:
int roomID;
public;
FloorTile(int inLocX, int inLocY, int inRoomID):Tile(inLocX, inLocY)
{
setRoomID(roomID); }
void setRoomID(int inRoomID){ roomID = inRoomID; }
int getRoomID(){ return roomID; }
}//end of FloorTile class

the idea is that i have a 2d array called map which holds tiles of
various kinds inlcuding wall, void and as seen above, floor. All of
that works fine, but when i look up, for example the tile at position
10,10 and i *know* that it is a floor tile, calling setRoomID() doenst
work. Origional code looks somthing like this:
map[10][10].setRoomID(15);
ive been shotgun programming it all afternoon, the best idea ive had
is pretty ugly, but still wont work because FloorTile is non-scalar
and cant be cast like thus:
FloorTile tempTile = map[10][10];
tempTile.setRoomID(15);
I guess what i need is some way to get it recognising the difference
between the types of tiles, once theyre pulled out of the array,
thereby opening the possibility of accessing the methods of the
subclass, but i have no idea...

sorry for noobing it up, im pretty sure this is a stupid thing to get
stuck on :p

-Numeron
 
Z

Zeppe

Numeron said:
This is part of my first ever largish project, a tile based game. I
havent got a lot of experience with c++ so be nice ;)

this is all within Tile.h, a lot has been taken out or simplified for
the sake of...er simplicity lol.

class Tile{
private:
int locationX;
int locationY;
public:
Tile(int inLocX, int inLocY){
setLocX(inLocX);
setLocY(inLocY); }
void setLocX(int inLocX){ locationX = inLocX; }
void setLocY(int inLocY){ locationY = inLocY; }
int getLocX(){ return locationX; }
int getLocY(){ return locationY; }
}//end of Tile class

class FloorTile : public Tile{
private:
int roomID;
public;
FloorTile(int inLocX, int inLocY, int inRoomID):Tile(inLocX, inLocY)
{
setRoomID(roomID); }
void setRoomID(int inRoomID){ roomID = inRoomID; }
int getRoomID(){ return roomID; }
}//end of FloorTile class

the idea is that i have a 2d array called map which holds tiles of
various kinds inlcuding wall, void and as seen above, floor. All of
that works fine, but when i look up, for example the tile at position
10,10 and i *know* that it is a floor tile, calling setRoomID() doenst
work.

How can you know it? I'm pretty curious to know how you declare your 2d
vector. If it is a Tile[][], all your tiles are basic tiles. The
(design) problem anyway is not so trivial, even though it's quite common
and there is a choice of solutions depending on the particular situation.

Regards,

Zeppe
 
N

Numeron

How can you know it? I'm pretty curious to know how you declare your 2d
vector. If it is a Tile[][], all your tiles are basic tiles. The
(design) problem anyway is not so trivial, even though it's quite common
and there is a choice of solutions depending on the particular situation.

declaring looks something like this:

Tile map[78][39];

void InitializeMap(){
//Iterates through the map filling it with floor tiles
int x = 0; int y = 0;
while ((x != 78) && (y != 39)){
map[x][y] = new FloorTile(x,y,0);
x++;
if (x == 78){ y++; x = 0; }
}
}

once the initialise map method is called they're *all* floor tiles, so
any tile pulled from the map array must also be a floor tile..

-Numeron
 
Z

Zeppe

Numeron said:
How can you know it? I'm pretty curious to know how you declare your 2d
vector. If it is a Tile[][], all your tiles are basic tiles. The
(design) problem anyway is not so trivial, even though it's quite common
and there is a choice of solutions depending on the particular situation.

declaring looks something like this:

Tile map[78][39];

void InitializeMap(){
//Iterates through the map filling it with floor tiles
int x = 0; int y = 0;
while ((x != 78) && (y != 39)){
map[x][y] = new FloorTile(x,y,0);

This won't compile. Something like "invalid conversion from
'FloorTile*"' to 'Tile'", I guess. Anyway, assuming you didn't wat to
use the new, I'm afraid in the map all the Tiles are just simple Tiles,
and the FloorTile that you assign in the floor is converted implicitly
into a Tile object. If you want polymorphism, you have to use pointers:

Tile* map[78][39];

for(...)
for(...)
map[j] = new [whatever you want]

and then, when you want to access the FloorTile members, you can do a
static_cast<FloorTile*>(map[j])->floorTileMethod();
of course, this is going to terminate badly your program if map[j] is
not a FloorTile. In order to prevent so, you can test the type with a
dynamic_cast, having the type enumerated in the base class, or any other
possibly fancier option.

Regards,

Zeppe
 
T

Tadeusz B. Kopec

On Tue, 27 Nov 2007 07:48:27 -0800, Numeron wrote:
[FloorTile is a subclass of Tile - introduces new method]
How can you know it? I'm pretty curious to know how you declare your 2d
vector. If it is a Tile[][], all your tiles are basic tiles. The
(design) problem anyway is not so trivial, even though it's quite
common and there is a choice of solutions depending on the particular
situation.

declaring looks something like this:

Tile map[78][39];

void InitializeMap(){
//Iterates through the map filling it with floor tiles int x = 0;
int y = 0;
while ((x != 78) && (y != 39)){
map[x][y] = new FloorTile(x,y,0);
x++;
if (x == 78){ y++; x = 0; }
}
}

once the initialise map method is called they're *all* floor tiles, so
any tile pulled from the map array must also be a floor tile..

First of all - your code doesn't compile - the line
map[x][y] = new FloorTile(x, y, 0);
The left side of assignment has type Tile, while the right side is of
type FloorTile*. Maybe your array has type
Tile *map[78][39];

Second - if the whole array contains objects of FloorTile, why bother
with declaring it as containing objects of class Tile?
 
N

Numeron

Zeppe said:
Tile* map[78][39];


for(...)
for(...)
map[j] = new [whatever you want]


and then, when you want to access the FloorTile members, you can do a
static_cast<FloorTile*>(map[j])->floorTileMethod();


thanks for this it will be immesurably helpful. i understand how
pointers work, but in practice its a bit tricky to get right, but hey,
i guess i need to learn sometime ;)
Second - if the whole array contains objects of FloorTile, why bother
with declaring it as containing objects of class Tile?

basically thats jsut the first part of the level generating
algorithm.. fills with floor, puts walls in tiles to give rectangled
rooms, adds some other stuff etc. so that the whole thing turns out to
look something like an old 'roguelike' game.

-Numeron
 
T

Tadeusz B. Kopec

Numeron said:
How can you know it? I'm pretty curious to know how you declare your
2d vector. If it is a Tile[][], all your tiles are basic tiles. The
(design) problem anyway is not so trivial, even though it's quite
common and there is a choice of solutions depending on the particular
situation.

declaring looks something like this:

Tile map[78][39];

void InitializeMap(){
//Iterates through the map filling it with floor tiles int x = 0;
int y = 0;
while ((x != 78) && (y != 39)){
map[x][y] = new FloorTile(x,y,0);

This won't compile. Something like "invalid conversion from
'FloorTile*"' to 'Tile'", I guess. Anyway, assuming you didn't wat to
use the new, I'm afraid in the map all the Tiles are just simple Tiles,
and the FloorTile that you assign in the floor is converted implicitly
into a Tile object. If you want polymorphism, you have to use pointers:

Tile* map[78][39];

for(...)
for(...)
map[j] = new [whatever you want]

and then, when you want to access the FloorTile members, you can do a
static_cast<FloorTile*>(map[j])->floorTileMethod(); of course, this
is going to terminate badly your program if map[j] is not a
FloorTile. In order to prevent so, you can test the type with a
dynamic_cast, having the type enumerated in the base class, or any other
possibly fancier option.


It's good to note that using static_casts and dynamic_casts often
indicates poor design. I bet this is the case.
I also noticed that Tile has no virtual destructor although it is used
polymorphically. On deletion there will be undefined behaviour.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top