Естественно это не скомпилируется сразу - это только первые наметки, еслои так можно сказать. Суть данного метода в том что можно сделать как раз обертку на уже готовый функционал. С помощью шаблонов все это можно расширить таким образом чтобы при наследовании от уже написанного ранее класса алгоритма (не по данной схеме) его конструктор вызывался автоматом, после чего можно получить более красивые вещи, например, для регистрации алгоритмов использовать более хитрые шаблоны, более корректно проверяющие что им подают в качестве параметров шаблона...
Еще раз повторяю что все что приведено ниже это просто наметки и намеки, на то как можно сделать.
Код:
class ArgumentsList
{
private:
//...
public:
ArgumentsList() {}
ArgumentsList(const ArgumentsList& other)
{
*this = other;
}
ArgumentsList &operator=(const ArgumentsList& other)
{
if (this != &other)
{
//Копируем все что надо
}
return *this;
}
~ArgumentsList() {};
};
class Results
{
public:
Results();
//Вся реализация конструкторы копирования и т.п.
~Results();
};
// Базовый клас алгоритма.
class BaseAlgoritm
{
private:
std::string m_invokedMethod;
protected:
void dummyTest();
public:
IBaseAlgoritm(const std::string& methodName)
: m_invokedMethod(methodName)
{
}
virtual ~IBaseAlgoritm()
(
)
virtual const std::string& invikedMethod() const
{
return m_invokedMethod;
}
virtual bool canProccess(const std::string& methodName)
{
return (methodName == m_invokedMethod);
}
virtual Results proccess(const ArgumentsList& args) = 0;
};
class Algoritm
: public BaseAlgoritm
{
public:
Algoritm(const std::string& methodName)
: BaseAlgoritm(methodName)
{
dummyTest();
}
virtual ~Algoritm()
(
)
};
//Предположим что есть класссы A1 и B1 которые что-то там делают... Нам нужно на их основе написать свои алгоритмы...
//Делаем наследника от A1
class AA1
: public A1
, public Algoritm
{
AA1(int a, int b, int c)
: A1(a, b, c)
, Algoritm("m1")
{}
virtual ~AA1() {}
//Реализуем функцию которая будет выполнять действия...
virtual Results proccess(const ArgumentsList& args)
{
retrun A1::m1(args);
}
};
//Аналогично для B1
class BB1
: public B1
, public Algoritm
{
BB1(int a, int b)
: B1(a, b)
, Algoritm("m2")
{}
virtual ~BB1() {}
//Реализуем функцию которая будет выполнять действия...
virtual Results proccess(const ArgumentsList& args)
{
retrun B1::m2(args);
}
};
// так далее. Суть в том что каждый наследник класса-примеси Algoritm обязан реализовать proccess, таким образом имеем общий интерфейс для все алгоритмов реализованных подобным образом.
// По идее можно не использовать примесь в виде уже реализованного класса, а просто делать наследника от Algoritm и реализовывать его соотв образом.
// Интерпретатор примет рпимерно такой вид:
class Interpret
{
private:
typedef std::list<BaseAlgoritm *> AList;
AList m_algoritms;
public:
Interpret() {}
virtual ~Interpret()
{
while (m_algoritms.size() > 0)
{
delete *(m_algoritms.begin());
m_algoritms.erase(m_algoritms.begin());
}
}
Results invore(const std::string &method, const ArgumentsList& args)
{
AList::const_iterator i = m_algoritms.begin();
AList::const_iterator ei = m_algoritms.end();
for (; i != ei; ++i)
{
if ((*i)->canProccess(method))
return (*i)->proccess(args)
}
return Results();
}
bool contains(const std::string &method)
{
AList::const_iterator i = m_algoritms.begin();
AList::const_iterator ei = m_algoritms.end();
for (; i != ei; ++i)
{
if ((*i)->canProccess(method))
return true;
}
return false;
}
template <class AT>
void register(int a, int b, int c)
{
AT* newalg = new AT(a, b, c);
if (!contains(newalg->invikedMethod()))
m_algoritms.push_back(newalg);
else
delete newalg;
}
template <class AT>
void register(int a, int b)
{
AT* newalg = new AT(a, b);
if (!contains(newalg->invikedMethod()))
m_algoritms.push_back(newalg);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Interpret tmp;
tmp.register<AA1>(10,5.3);
tmp.register<BB1>(5,22);
ArgumentsList lst1;
ArgumentsList lst2;
Results rr = tmp.invore("m1", lst1);
Results rr1 = tmp.invore("m2", lst2);
}