Professional C__ - Marc Gregoire [338]
Examine the new templatized copy constructor first:
template Grid(const Grid You can see that there is another template declaration with a different typename, E (short for “element”). The class is templatized on one type, T, and the new copy constructor is also templatized on a different type, E. This twofold templatization allows you to copy grids of one type to another. Here is the definition of the new copy constructor: template template Grid { copyFrom(src); } Code snippet from MethodTemplates\Grid.h As you can see, you must declare the class template line (with the T parameter) before the member template line (with the E parameter). You can’t combine them like this: template Grid The copy constructor uses the protected copyFrom() method, so the class needs a templatized version of copyFrom() as well: template template void Grid { mWidth = src.getWidth(); mHeight = src.getHeight(); 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.getElementAt(i, j); } } } Code snippet from MethodTemplates\Grid.h In addition to the extra template parameter line before the copyFrom() method definition, note that you must use public accessor methods getWidth(), getHeight(), and getElementAt() to access the elements of src. That’s because the object you’re copying to is of type Grid The final templatized method is the assignment operator. Note that it takes a const Grid template template Grid { // 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; } Code snippet from MethodTemplates\Grid.h You do not need to check for self-assignment in the templatized assignment operator, because assignment of the same types still happens in the old, non-templatized, version of operator=, so there’s no way you can get self-assignment here. Method Templates with Non-Type Parameters In the earlier example with integer template parameters for HEIGHT and WIDTH, you see that a major problem is that the height and width become part of the types. This restriction prevents you from assigning a grid with one height and width to a grid with a different height and width. In some cases, however, it’s desirable to assign or copy a grid of one size to a grid of a different size. Instead of making the destination object a perfect clone of the source object, you would copy only those elements from the source array that fit in the destination array, padding the destination array with default values if the source array is smaller in either dimension. With method templates for the assignment operator and copy constructor, you can do exactly that, thus allow assignment and copying of different sized grids. Here is the class definition: template class Grid { public: Grid() {} template Grid(const Grid