Well from what I'm seeing, I wouldn't recommend learning C++ from this guy's tutorials. This code is atrocious (even if work out all the allocation errors and heap corruption that's going on)
But whatever. Here's your explanation:
1 2 3 4 5
|
const int COLUMNS = 10;
const int ROWS = 5;
typedef MapItem* col[COLUMNS];
typedef col* gridtype[ROWS];
|
'col' is an array of pointers. Each pointer points to a MapItem.
'gridtype' is an array of pointers. Each pointer points to a col
Therefore a gridtype is an array of pointers that points to an array of pointers which point to MapItem. Yes it's confusing.
To declare 'grid' without the gridtype typedefs... you could do this:
|
MapItem *(*grid[ROWS])[COLUMNS];
|
The parenthesis here are necesary because you have an array of pointers to arrays. Without the parenthesis you have this:
|
MapItem** grid[ROWS][COLUMNS];
|
Which is not an array of pointers to arrays of pointers to MapItems.... instead it's a singular 2D array of pointers to pointers (rather than two 1D arrays)
Moving on:
|
(*grid[i])[j] = new MapItem(i,j);
|
Let's break this down one operator at a time:
Remember that 'grid' is first and foremost an array (an array of pointers)... therefore 'grid[i]' gets you one pointer from the array (ie: the pointer for the current row).
Next, '*grid[i]' dereferences that pointer, which means '*grid[i]' is of type 'col' So you could do this:
(note that I have to use a reference
col&
here because col is an array and therefore you can't assign it like it was a singular variable)
Moving on... '*grid[i]' is a 'col'. And remember that 'col' is first and foremost an array (array of pointers to MapItems)
Therefore: (*grid[i])[j] gets one pointer from the array of pointers. That pointer points to a single MapItem... so you cold do this:
|
MapItem* test = (*grid[i])[j];
|
The parenthesis are key here because the braket operator [] has a higher priority than the dereference operator *.
If you take out the parenthesis you have a compeltely different expression.
It works out fine for [0][0] because [0] and * effectively mean the exact same thing... but if you want to do, say, [1][2], you're in for a lot of trouble. For example:
1 2
|
(*grid[1])[2]->line = "This is ok";
(*grid[1][2])->line = "This is BAD. Bad pointers, heap corruption, etc";
|
The reason these are so different is because the braket operator [] has a higher priority than the dereference operator *.
In the first 'ok' version, the []s index each of the arrays, as outlined above. Therefore *grid[1] is our col (ie: the same as grid[1][0])
In the BAD version, the [2] dereferences a pointer and the * indexes an array! Therefore grid[1][2] is our col (not grid[1][0] as above!)
Anyway that's about as into it as I'm going to be able to get. Again, I really don't recommend this crap. I'd stop reading this guy's tutorials, too. Like I say.. if there's anything you can learn from this, it's "Things to never do in programming"