Online Book Reader

Home Category

Professional C__ - Marc Gregoire [353]

By Root 1508 0

template

OneDGrid::~OneDGrid()

{

delete [] mElems;

mElems = nullptr;

}

template

void OneDGrid::copyFrom(const OneDGrid& src)

{

mSize = src.mSize;

mElems = new T[mSize];

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

mElems[i] = src.mElems[i];

}

}

template

OneDGrid& OneDGrid::operator=(const OneDGrid& rhs)

{

// Check for self-assignment.

if (this == &rhs) {

return *this;

}

// Free the old memory.

delete [] mElems;

mElems = nullptr;

// Copy the new memory.

copyFrom(rhs);

return *this;

}

template

void OneDGrid::resize(size_t newSize)

{

T* newElems = new T[newSize]; // Allocate the new array of the new size

// Handle the new size being smaller or bigger than the old size.

for (size_t i = 0; i < newSize && i < mSize; i++) {

// Copy the elements from the old array to the new one.

newElems[i] = mElems[i];

}

mSize = newSize; // Store the new size.

delete [] mElems; // Free the memory for the old array.

mElems = newElems; // Store the pointer to the new array.

}

template

T& OneDGrid::operator[](size_t x)

{

return mElems[x];

}

template

const T& OneDGrid::operator[](size_t x) const

{

return mElems[x];

}

Code snippet from OneDGrid\OneDGrid.h

With this implementation of the OneDGrid, you can create multidimensional grids like this:

OneDGrid singleDGrid;

OneDGrid> twoDGrid;

OneDGrid>> threeDGrid;

singleDGrid[3] = 5;

twoDGrid[3][3] = 5;

threeDGrid[3][3][3] = 5;

Code snippet from OneDGrid\OneDGridTest.cpp

This code works fine, but the declarations are messy. We can do better.

A Real N-Dimensional Grid

You can use template recursion to write a “real” N-dimensional grid because dimensionality of grids is essentially recursive. You can see that in this declaration:

OneDGrid>> threeDGrid;

You can think of each nesting OneDGrid as a recursive step, with the OneDGrid of int as the base case. In other words, a three-dimensional grid is a single-dimensional grid of single-dimensional grids of single-dimensional grids of ints. Instead of requiring the user to do this recursion, you can write a template class that does it for you. Then, you can create N-dimensional grids like this:

NDGrid singleDGrid;

NDGrid twoDGrid;

NDGrid threeDGrid;

The NDGrid template class takes a type for its element and an integer specifying its “dimensionality.” The key insight here is that the element type of the NDGrid is not the element type specified in the template parameter list, but is in fact another NDGrid of dimensionality one less than the current. In other words, a three-dimensional grid is an array of two-dimensional grids; the two-dimensional grids are each arrays of one-dimensional grids.

With recursion, you need a base case. You can write a partial specialization of the NDGrid for dimensionality of 1, in which the element type is not another NDGrid, but is in fact the element type specified by the template parameter.

Here is the general NDGrid template definition, with highlights showing where it differs from the OneDGrid shown in the previous section:

template

class NDGrid

{

public:

NDGrid();

NDGrid(size_t inSize);

NDGrid(const NDGrid& src);

virtual ~NDGrid();

NDGrid& operator=(const NDGrid& rhs);

void resize(size_t newSize);

NDGrid& operator[](size_t x);

const NDGrid& operator[](size_t x) const;

size_t getSize() const { return mSize; }

static const size_t kDefaultSize = 10;

protected:

void copyFrom(const NDGrid& src);

NDGrid* mElems;

size_t mSize;

};

Code snippet from NDGrid\NDGrid.h

Note that mElems is a pointer to an NDGrid: This is the recursive step. Also, operator[] returns a reference to the element type, which is again NDGrid, not T.

Here is the template definition for the base case:

template

class NDGrid

{

public:

NDGrid(size_t inSize = kDefaultSize);

NDGrid(const

Return Main Page Previous Page Next Page

®Online Book Reader