class grid{
public:
class CELL{
public:
int Height(int index); //returns the height of this cell
};
std::vector<CELL> Cell;
};
int main()
{
grid gx;
/* Initialize Cell[size] */
gx.Cell[4].Height(4);
}
I'm trying to keep the code simple to better explain the problem. I know the example doesn't show the Cell vector initialized. But that's not my issue, I know how to do that.
I also know Height() doesn't need a parameter. However, there are other functions I plan to implement, such as CellCenter() which will return a 'point' that's equal to the center of the grid cell. To do this, I need to know that I'm on cell 4, or whatever.
I'm just trying to figure out how to pass a vector index to a function such as in the example above. I'm almost to the point of assuming it's beyond the scope of C++.
CELL::CELL(int index, /*...*/) //CELL object will know its own index
//...
grid::grid() //default constructor
{
for(int i = 0; i < CELL_COUNT; ++i)
Cell.emplace_back( i + 1, /*...*/); //Assuming Cells are counted from 1
}
I wrote in my suggestion: store cell number in CELL itself. Another way is to make operator[] of grid return wrapper.
Like:
1 2 3 4 5 6 7 8 9 10 11 12 13
class cell_wrapper
{
CELL& value;
int index;
cell_wrapper(int ind, CELL& v) : value(v), index(ind) {};
//Some functions working with both CELL and index or passing calls to CELL.
}
cell_wrapper grid::operator[](int index)
{
return cell_wrapper(index, Cell[index]) //Returning Index aware CELL adapter
}
And last: if some methods does not have sense for CELL object without encompassing grid, it should not be member of CELL.
as CellCenter() which will return a 'point' that's equal to the center of the grid cell.
How should that function work if you create standalone CELL object? If your answer "it shouldn't" then it shouldn't be CELL member.
So are you trying to say that you need to pass a value to the cell that is the same as it's position in the grid? The easiest way would simply to give the Cell its position in the grid upon construction. If Cell's move around, then you can probably add a set function to change it, but otherwise its fine. So in your example:
Thanks to both of you for being so helpful. It's my fault for not explaining my problem more clearly the first time, so let me start again with a bit more detail.
For a visual of the 'grid' where each number represents the 'index' of a single cell, think of a Checkers board or any tile-based game. I'm building this for game programming utilizing Allegro 5 for my graphics library.
The 'point' class below is defined elsewhere, but simply explained it just contains an X and Y integer value that represents a pixel position.
class grid{
public:
class cell{
point UpperLeftCorner()
{
//Would calculate the upper point position of this cell.
//To do so, need to know which cell index we are working with.
//Would like to figure out how to extract Cell vector index,
//without having to pass a parameter thru UpperLeftCorner().
}
};
std::vector<cell> Cell;
void Create(int rows, int columns, int cellsWidth, int cellsHeight)
{
//Error check here
gRows = rows;
gColumns = columns;
cWidth = cellsWidth;
cHeight = cellsHeight;
cell tmpCell;
for (int i=0; i<(rows*columns); ++i)
Cell.push_back(tmpCell);
//First cell of the grid would be index = 0; last cell would be Cell.size()-1
}
//Returns grid Height / Width
int Height() { return (gRows*cHeight); }
int Width() { return (gColumns*cWidth); }
int CellCount() { return (gRows*gColumns); }
private:
int gRows;
int gColumns;
int cWidth;
int cHeight;
};
So for example, if I were to implement this....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int main()
{
grid g;
//Creates a grid with dimensions 5x5 cells (25 cells total indexed 0 thru 24)
//Each cell is 32 pixels width by 32 pixels height
g.Create(5,5,32,32);
//Get the upper left pixel position of the 4th (for example) cell
point thisCell = g.Cell[3].UpperLeftCorner();
//I could later use 'thisCell' to draw a graphic or track a sprite's movement
// thisCell.X = upper left X value of 4th cell indexed 3
//thisCell.Y = upper left Y value of 4th cell indexed 3
}
So in summary, my questions revolves around how do I 'pass' the literal '3' from this statement in the main() function without having to add a parameter to the UpperLeftCorner() function? point thisCell = g.Cell[3].UpperLeftCorner();
//Would calculate the upper point position of this cell.
//To do so, need to know which cell index we are working with.
//Would like to figure out how to extract Cell vector index,
//without having to pass a parameter thru UpperLeftCorner().
If class needs to know something about other class to do some operation then this operation is not his responsibility.
class grid
{
point UpperLeftCorner(int index)
{
//Calculate UL corner depending on board size etc...
}
}
//...
g.UpperLeftCorner(3);
//or
class grid
{
class CellWrapper
{
int index;
CELL& target;
grid& owner;
point UpperLeftCorner()
{
point UL = owner.Height() / owner.gRows * index %//... etc
}
operator CELL() { return target; } //Conversion
};
operator[](int index)
{
return CellWrapper(index, Cell[index], *this) //Returning Index aware CELL adapter
}
};
//...
point thisCell = g.Cell[3].UpperLeftCorner(); //Almost like in your code