Некоторое время назад я узнал о Curiously Recurring Template Pattern (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) и напомнил мне о технике, которую я использовал для реализации кеша очереди событий.Техника использования шаблонов и виртуальных функций
Основная идея заключается в том, что мы используем указатель базового класса для хранения контейнера с однородными типами указателей. Однако поскольку класс Derived является классом шаблона, в котором хранится элемент типа T, то мы действительно сохраняем список гетерогенных типов.
Мне было любопытно, если кто-нибудь видел эту технику, которая, возможно, интересна, и если да, если кто-то назвал ее? Кто-нибудь хочет критиковать его? Есть ли лучший способ достичь моего конца здесь?
Спасибо.
#include <iostream>
#include <algorithm>
#include <functional>
#include <list>
#include <string>
class Base
{
public:
Base(){}
virtual ~Base(){}
virtual void operator()() = 0;
};
template<typename C, typename T>
class Derived : public Base
{
public:
Derived(C* c, T item) : consumer_(c), item_(item) {}
virtual void operator()()
{
consumer_->consume(item_);
}
C* consumer_;
T item_;
};
class Consumer
{
bool postpone_;
std::list<Base*> cache_;
public:
Consumer() : postpone_(true)
{
}
void pause()
{
postpone_ = true;
}
void resume()
{
postpone_ = false;
const std::list<Base*>::iterator end = cache_.end();
for (std::list<Base*>::iterator iter = cache_.begin();
iter != end;
++iter)
{
Base* bPtr = *iter;
bPtr->operator()();
delete bPtr;
}
cache_.clear();
}
void consume(int i)
{
if (postpone_)
{
std::cerr << "Postpone int.\n";
cache_.push_back(new Derived<Consumer, int>(this, i));
}
else
{
std::cerr << "Got int.\n";
}
}
void consume(double d)
{
if (postpone_)
{
std::cerr << "Postpone double.\n";
cache_.push_back(new Derived<Consumer, double>(this, d));
}
else
{
std::cerr << "Got double.\n";
}
}
void consume(char c)
{
if (postpone_)
{
std::cerr << "Postpone char.\n";
cache_.push_back(new Derived<Consumer, char>(this, c));
}
else
{
std::cerr << "Got char.\n";
}
}
};
static Consumer consumer;
void destroy(Base* object)
{
delete object;
}
int main()
{
// Consumer is registered with something that sends events out to lots
// of different consumer types (think observer pattern). Also in the non-toy
// version consumer isn't being passed PODs, but various Event types.
consumer.consume(0);
consumer.consume(0.1f);
consumer.consume('x');
consumer.resume();
}
Выход:
Postpone int.
Postpone double.
Postpone char.
Got int.
Got double.
Got char.
Я считаю, это называется «полиморфизм»;) – Stephen