Online Book Reader

Home Category

Professional C__ - Marc Gregoire [199]

By Root 1179 0
access a type based on one or more template parameters. In this case, the template parameter T is used to access the iterator type. Thus, you must specify typename. This is another example of arcane C++ syntax.

The class also prevents assignment and pass-by-value because of the mCurElem data member. To make assignment and pass-by-value work you would have to implement an assignment operator and copy constructor and make sure mCurElem is valid in the destination object. This is omitted in this example.

The implementation of the RoundRobin class follows with comments explaining the code. Note the use of reserve() in the constructor, and the extensive use of the iterator in add(), remove(), and getNext(). The trickiest aspect is keeping mCurElem valid and referring to the correct element following calls to add() or remove().

template

RoundRobin::RoundRobin(int numExpected)

{

// If the client gave a guideline, reserve that much space.

mElems.reserve(numExpected);

// Initialize mCurElem even though it isn't used until

// there's at least one element.

mCurElem = mElems.begin();

}

template

RoundRobin::~RoundRobin()

{

// nothing to do here -- the vector will delete all the elements

}

// Always add the new element at the end

template

void RoundRobin::add(const T& elem)

{

// Even though we add the element at the end, the vector could

// reallocate and invalidate the iterator with the push_back call.

// Take advantage of the random access iterator features to save our

// spot.

int pos = mCurElem - mElems.begin();

// add the element

mElems.push_back(elem);

// Reset our iterator to make sure it is valid.

mCurElem = mElems.begin() + pos;

}

template

void RoundRobin::remove(const T& elem)

{

for (auto it = mElems.begin(); it != mElems.end(); ++it) {

if (*it == elem) {

// Removing an element will invalidate our mCurElem iterator if

// it refers to an element past the point of the removal.

// Take advantage of the random access features of the iterator

// to track the position of the current element after removal.

int newPos;

// If current iterator is before or at the one we're removing,

// the new position is the same as before.

if (mCurElem <= it) {

newPos = mCurElem - mElems.begin();

} else {

// otherwise, it's one less than before

newPos = mCurElem - mElems.begin() - 1;

}

// erase the element (and ignore the return value)

mElems.erase(it);

// Now reset our iterator to make sure it is valid.

mCurElem = mElems.begin() + newPos;

// If we were pointing to the last element and it was removed,

// we need to loop back to the first.

if (mCurElem == mElems.end()) {

mCurElem = mElems.begin();

}

return;

}

}

}

template

T& RoundRobin::getNext() throw(std::out_of_range)

{

// First, make sure there are any elements.

if (mElems.empty()) {

throw std::out_of_range("No elements in the list");

}

// retrieve a reference to return

T& retVal = *mCurElem;

// Increment the iterator modulo the number of elements

++mCurElem;

if (mCurElem == mElems.end()) {

mCurElem = mElems.begin();

}

// return the reference

return retVal;

}

Code snippet from RoundRobin\RoundRobin.h

Here’s a simple implementation of a scheduler that uses the RoundRobin class template, with comments explaining the code.

// Simple Process class.

class Process

{

public:

// Constructor accepting the name of the process.

Process(const string& name) : mName(name) {}

// Implementation of doWorkDuringTimeSlice would let the process

// perform its work for the duration of a time slice.

// Actual implementation omitted.

void doWorkDuringTimeSlice() {

cout << "Process " << mName

<< " performing work during time slice." << endl;

}

// Needed for the RoundRobin::remove method to work.

bool operator==(const Process& rhs) {

return mName == rhs.mName;

}

protected:

string mName;

};

// Simple round-robin based process scheduler.

class Scheduler

{

public:

// Constructor takes a vector of processes.

Scheduler(const vector&

Return Main Page Previous Page Next Page

®Online Book Reader