Существует две оси вариации в письме: выбор write0 / write1 и выбор MsgA / B / C .....
Концептуально это означает, что вам нужны реализации NxM функции write
. Конечно, если добавлена реализация записи или тип сообщения, это приводит к соотв. M или N дополнительных функций, которые будут добавлены.
Для обеих осей вы можете выбрать, применять ли их статический или динамический полиморфизм. Статический полиморфизм может быть выполнен с использованием шаблонов или переопределений функций.
Это можно сделать, создав иерархию классов N элементов с M функциями записи в каждом классе. Но это скоро станет кошмаром обслуживания. Если содержимое сообщения также не является полиморфным во время выполнения. Но вопрос о статическом полиморфизме сообщений.
Поскольку полиморфизм во время выполнения исключен из-за слишком сложной (и у вас не может быть виртуальной функции шаблона, которая могла бы уменьшить многословность переопределений), нам нужно реализовать небольшую подпрограмму диспетчеризации типов, преобразующую информацию времени выполнения в компиляцию информация.
Более конкретно: шаблонизируйте основное действие (в примере с именем Tmain
) с помощью редактора и вызовите его с правильным аргументом шаблона из 'real' main
.
Это исключает использование переменной глобального выбора, но в то же время является объектно-ориентированным и кратким.
// twodimensionalpolymorph.cpp
//
#include <iostream>
using namespace std;
class Write0 {
public:
template< typename tMsg >
void operator()( /*const*/ tMsg& msg ) { cout << "write0: " << msg.name() << endl; };
};
class Write1 {
public:
template< typename tMsg >
void operator()( /*const*/ tMsg& msg ) { cout << "write1: "<< msg.name() << endl; };
};
struct MsgA { const char *name() { return "MsgA"; } };
struct MsgB { const char *name() { return "MsgB"; } };
struct MsgC { const char *name() { return "MsgC"; } };
struct MsgD { const char *name() { return "MsgD"; } };
// the Tmain does the real action
//
template< typename Writer >
int Tmain( Writer& write, int argc, char** args ) {
write( MsgA() );
write( MsgB() );
write( MsgB() );
write( MsgD() );
return 0;
}
// the main merely chooses the writer to use
//
int main( int argc, char** args ) {
if( argc==1 )
return Tmain( Write0(), argc, args);
else
return Tmain( Write1(), argc, args);
}