Professional C__ - Marc Gregoire [333]
Within a class definition, the compiler will interpret Grid as Grid The final change to the class is that methods such as setElementAt() and getElementAt() now take and return parameters and values of type T instead of type GamePiece: void setElementAt(size_t x, size_t y, const T& inElem); T& getElementAt(size_t x, size_t y); const T& getElementAt(size_t x, size_t y) const; This type T is a placeholder for whatever type the user specifies. mCells is now a T** instead of a GamePiece** because it will point to a dynamically allocated two-dimensional array of Ts, for whatever type T the user specifies. The Grid Class Method Definitions The template template Grid { mCells = new T* [mWidth]; for (size_t i = 0; i < mWidth; i++) { mCells[i] = new T[mHeight]; } } Code snippet from Grid\Grid.h Templates require you to put the implementation of the methods in the header file itself, because the compiler needs to know the complete definition including the definition of methods before it can create an instance of the template. This is discussed in more details later in this chapter. Note that the class name before the :: is Grid The rest of the method definitions are also similar to their equivalents in the GameBoard class with the exception of the appropriate template and Grid template Grid { copyFrom(src); } template Grid { // Free the old memory. for (size_t i = 0; i < mWidth; i++) { delete [] mCells[i]; } delete [] mCells; mCells = nullptr; } template void Grid { mWidth = src.mWidth; mHeight = src.mHeight; mCells = new T* [mWidth]; for (size_t i = 0; i < mWidth; i++) { mCells[i] = new T[mHeight]; } for (size_t i = 0; i < mWidth; i++) { for (size_t j = 0; j < mHeight; j++) { mCells[i][j] = src.mCells[i][j]; } } } template Grid { // Check for self-assignment. if (this == &rhs) { return *this; } // Free the old memory. for (size_t i = 0; i < mWidth; i++) { delete [] mCells[i]; } delete [] mCells; mCells = nullptr; // Copy the new memory. copyFrom(rhs); return *this; } template void Grid { mCells[x][y] = inElem; } template T& Grid { return mCells[x][y]; } template const T& Grid { return mCells[x][y]; } Code snippet from Grid\Grid.h Using the Grid Template When you want to create grid objects, you cannot use Grid alone as a type; you must specify the type that will be stored in that Grid. Creating an object of a template class for a specific type is called instantiating the template. Here is an example: Grid // using default parameters for the constructor Grid int x = myIntGrid.getElementAt(0, 0); Grid Grid Code snippet from Grid\GridTest.cpp Note that the type of myIntGrid, grid2,