Online Book Reader

Home Category

Professional C__ - Marc Gregoire [333]

By Root 1419 0
and return value from, the assignment operator, and the parameter to the copyFrom() method.

Within a class definition, the compiler will interpret Grid as Grid where needed. However, it’s best to get in the habit of specifying Grid explicitly because that’s the syntax you use outside the class to refer to types generated from the template. Only for constructors and the destructor, you should use Grid and not 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 specifier must precede each method definition for the Grid template. The constructor looks like this:

template

Grid::Grid(size_t inWidth, size_t inHeight) : mWidth(inWidth), mHeight(inHeight)

{

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, not Grid. You must specify Grid as the class name in all your methods and static data member definitions. The body of the constructor is identical to the GameBoard constructor except that the placeholder type T replaces the GamePiece type.

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 syntax changes:

template

Grid::Grid(const Grid& src)

{

copyFrom(src);

}

template

Grid::~Grid()

{

// Free the old memory.

for (size_t i = 0; i < mWidth; i++) {

delete [] mCells[i];

}

delete [] mCells;

mCells = nullptr;

}

template

void Grid::copyFrom(const Grid& src)

{

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& Grid::operator=(const Grid& rhs)

{

// 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::setElementAt(size_t x, size_t y, const T& inElem)

{

mCells[x][y] = inElem;

}

template

T& Grid::getElementAt(size_t x, size_t y)

{

return mCells[x][y];

}

template

const T& Grid::getElementAt(size_t x, size_t y) const

{

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 myIntGrid; // declares a grid that stores ints,

// using default parameters for the constructor

Grid myDoubleGrid(11, 11); // declares an 11x11 Grid of doubles myIntGrid.setElementAt(0, 0, 10);

int x = myIntGrid.getElementAt(0, 0);

Grid grid2(myIntGrid);

Grid anotherIntGrid = grid2;

Code snippet from Grid\GridTest.cpp

Note that the type of myIntGrid, grid2,

Return Main Page Previous Page Next Page

®Online Book Reader