Основанный на политике C ++ дизайн …. базовый класс как сигнатон или не основанный на параметре шаблона.

OutputPolicy моего класса иногда идет к статическому / одноэлементному объекту, а иногда к объекту 1-к-1.

Не уверен, смогу ли я объяснить по-английски .. так вот желаемое поведение в псевдокоде:

template<
class Algo,
template<class> OutputPolicy
>
class AlgoBase : Algo, OutputPolicy<Algo>
{
};

class AlgoImp
{
public:
AlgoImp(string topic) {}
void OnData(
{
cout << " AlgoImp::OnData";
if ( .... )
NewMsg(msg);
}
};

class AlgoImp2
{
public:
AlgoImp2(string topic) {}
void OnData(
{
cout << " AlgoImp2::OnData";
if ( .... )
NewMsg(msg);
}
};

AlgoImp :: OnData выполняет некоторую обработку и вызывает NewMsg. Я пытаюсь отделить имплиментацию вызова NewMsg ().

template < class T>
class OutMessageQueueTcp
{
void NewMsg(string in)
{
//Should be a signgleton or static
cout << " OutMessageQueueTcp::NewMsg";
}
};

Если OutputPolicy — OutMessageQueueTcp (выше), тогда должен быть только один экземпляр OutputPolicy. Так что я должен был бы либо получить его из Singleton, либо где-нибудь использовать статическую переменную.

template <class T>
class OutMessageAsInput : AlgoBase<AlgoImp2, OutMessageQueueTcp>
{
void NewMsg(string in)
{
cout << " OutMessageAsInput::OnData";
AlgoBase<AlgoImp2, OutMessageQueueTcp>::NewMsg(in);
}
};

Если OutputPolicy имеет значение OutMessageAsInput (выше), тогда out становится входным для дочернего объекта и затем отправляется в OutMessageQueueTcp.

Вот главное.

main
{
AlgoBase<AlgoImp, OutMessageAsInput> myalgo1;
myalgo1.OnData("hi");
}

И мой желаемый результат:

AlgoImp::OnData
OutMessageAsInput::NewMsg
AlgoImp2::OnData
OutMessageQueueTcp::NewMsg

Что у меня действительно есть, так это коллекция объектов AlgoImp, каждый со своей темой и данными. AlgoImp генерирует outout, вызывая NewMsg. Иногда эти сообщения следует отправлять в Socket, а иногда они должны обрабатываться AlgoImp2.

Это решение будет принято во время компиляции. Каждый Алго будет делать разные вещи. Похоже, я пытаюсь сделать что-то вроде Аспект-ориентированного материала.

Вопрос:

Можно ли сделать базовый класс одноэлементным или обычным объектом, сделав его политикой? Есть ли шаблон дизайна для чего-то подобного? Может быть, какая-то фабрика?

Спасибо за помощь.

1

Решение

Чтобы все было просто — OutputPolicy на вашем уровне классов algo должен быть простой класс с простым методом. Конечно, вы можете реализовать это с помощью одноэлементных или статических методов из реального класса реализации:

template < class T>
class OutMessageQueueTcp
{
public:
void NewMsg(string in)
{
impl.NewMsg(in);
}
private:
static OutMessageQueueTcpImpl<T> impl;
};

Или же:

template < class T>
class OutMessageQueueTcp
{
public:
void NewMsg(string in)
{
OutMessageQueueTcpImpl<T>::NewMsg(in);
}
};

Для тебя Algo* классы: если политика вывода задана во время компиляции — сделайте шаблон этих классов классным и обработайте OutputPolicy как Strategy — keeo оно агрегируется (как переменная-член) в ваших алгоритмах:

template <template <typename> class OutputPolicy>
class AlgoImp
{
public:
AlgoImp(string topic) {}
void OnData(
{
cout << " AlgoImp::OnData";
if ( .... )
outputPolicy.NewMsg(msg);
}
private:
OutputPolicy<AlgoImp> outputPolicy;
};
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]