参考C++ 高级编程,实现 vector 示例:循环调度类
round_robin.h
#include <vector>
#include <stdexcept>
using namespace std;
template<typename T>
class RoundRobin
{
public:
RoundRobin(int numExpected = 0);
~RoundRobin();
void add(const T& elem);
void remove(const T& elem);
T& getNext() throw(std::out_of_range);
private:
RoundRobin(const RoundRobin& src);
RoundRobin& operator=(const RoundRobin& rhs);
vector<T> mElems;
typename vector<T>::iterator mCurElem;
};
template<typename T>
RoundRobin<T>::RoundRobin(int numExpected)
{
mElems.reserve(numExpected);
mCurElem = mElems.begin();
}
template<typename T>
RoundRobin<T>::~RoundRobin()
{
}
template<typename T>
void RoundRobin<T>::add(const T& elem)
{
int pos = mCurElem - mElems.begin();
mElems.push_back(elem);
if (mElems.size() == 1)
{
mCurElem = mElems.begin();
}
else
{
mCurElem = mElems.begin() + pos;
}
}
template<typename T>
void RoundRobin<T>::remove(const T& elem)
{
for (typename vector<T>::iterator it = mElems.begin(); it != mElems.end(); ++it)
{
if (*it == elem)
{
int newPos;
if (mCurElem <= it)
{
newPos = mCurElem - mElems.begin();
}
else
{
newPos = mCurElem - mElems.begin() - 1;
}
mElems.erase(it);
mCurElem = mElems.begin() + newPos;
if (mCurElem == mElems.end())
{
mCurElem = mElems.begin();
}
return;
}
}
}
template<typename T>
T& RoundRobin<T>::getNext() throw(std::out_of_range)
{
if (mElems.empty())
{
throw std::out_of_range("no elements in list");
}
T& ret = *mCurElem;
++mCurElem;
if (mCurElem == mElems.end())
{
mCurElem = mElems.begin();
}
return ret;
}
load_balancer.h
#include "round_robin.h"
#include <iostream>
#include <string>
using namespace std;
class NetworkRequest
{
public:
NetworkRequest(const string& request)
{
mName = request;
cout << __FUNCTION__ << " " << mName << endl;
}
const string getName() const
{
return mName;
}
~NetworkRequest()
{
cout << __FUNCTION__ << " " << mName << endl;
}
private:
string mName;
};
class Host
{
public:
Host(const string& name)
{
mName = name;
cout << __FUNCTION__ << " " << mName <<endl;
}
void ProcessRequest(NetworkRequest& request)
{
cout << __FUNCTION__ << " " << mName << " " << request.getName() << endl;
}
~Host()
{
cout << __FUNCTION__ << " " << mName << endl;
}
private:
string mName;
};
class LoadBalancer
{
public:
LoadBalancer(const vector<Host>& hosts);
~LoadBalancer()
{
}
void distributeRequest(NetworkRequest& request);
private:
RoundRobin<Host> rr;
};
LoadBalancer::LoadBalancer(const vector<Host>& hosts)
{
for (size_t i = 0; i < hosts.size(); ++i)
{
rr.add(hosts[i]);
}
}
void LoadBalancer::distributeRequest(NetworkRequest& request)
{
try
{
rr.getNext().ProcessRequest(request);
}
catch (const std::out_of_range& e)
{
cout << e.what() << endl;
}
}
test.cpp
#include "load_balancer.h"
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
vector<Host> hosts;
hosts.reserve(5);
for (int i = 1; i <= 5; ++i)
{
stringstream ss;
ss << i;
string name = "host" + ss.str();
Host host(name);
hosts.push_back(host);
}
vector<NetworkRequest> requests;
requests.reserve(17);
for (int i = 1; i <= 17; ++i)
{
stringstream ss;
ss << i;
string name = "request" + ss.str();
NetworkRequest request(name);
requests.push_back(request);
}
LoadBalancer loadBalancer(hosts);
for (vector<NetworkRequest>::const_iterator it = requests.begin(); it != requests.end(); ++it)
{
NetworkRequest request = *it;
loadBalancer.distributeRequest(request);
}
return 0;
}