Estoy diseñando un mecanismo que ejecutará un conjunto de objetos de funciones unarias en secuencia. Estos objetos de función se asignan durante el tiempo de ejecución, y el problema es: el tipo de parámetro de estos objetos de función es diferente.¿Cómo ejecutar objetos de funciones unarias de diferentes tipos de parámetros en secuencia?
Lo que quiero hacer es algo como esto:
class command_sequence {
private:
/* some kind of container */
public:
void add(FUNC_OBJ &func, PARAM val);
void run(void);
};
class check_temperature {
public:
void operator() (int celsius) {
if(celsius > 26) {
cooler.switch_on();
}
}
};
class log_usage {
public:
void operator() (std::string username) {
username.append(" logged in");
syslog(LOG_NOTICE,username.c_str());
}
};
command_sequence sequence;
log_usage logger;
check_temperature checker;
sequence.add(logger, std::string("administrator"));
sequence.add(checker, lobbyMeter.read_temperature());
sequence.add(logger, std::string("lecture"));
sequence.add(checker, classroomMeter.read_temperature());
sequence.run();
Si estoy escribiendo código en C, no tengo más remedio devolución de llamada puntero de función que toma como parámetro void *. Pero ahora estoy trabajando con C++, debe haber una forma elegante de manejarlo.
La mejor manera que puedo pensar ahora está declarando una clase de plantilla que prácticamente heredan de una clase contenedora abstracta:
class command_sequence {
private:
class runner {
public:
virtual void execute(void) = 0;
};
template <class FUNC, typename T> class func_pair : public runner {
private:
FUNC &func;
T param;
public:
func_pair(FUNC &f, const T &t) : func(f),param(t) { }
void execute(void) {
func(param);
}
};
std::vector<runner*> funcQueue;
public:
template <class FUNC, typename T> void add(FUNC &obj, const T &t) {
funcQueue.push_back(new func_pair<FUNC,T>(obj,t));
}
void run(void) {
std::vector<runner*>::iterator itr=funcQueue.begin();
for(;itr!=funcQueue.end();++itr) {
(*itr)->execute();
delete (*itr);
}
}
};
Este enfoque puede adaptarse a mis necesidades, pero sería asignar y liberar template_pair para cada entrada. No tengo idea de si esto causaría fragmentos de memoria, ya que este procedimiento se llamará con bastante frecuencia durante el proceso.
¿Hay alguna forma mejor de hacerlo?
realmente impresionante. No tengo idea de que boost :: bind() puede aceptar objetos de función; pero tiene sentido. Esa parecía ser la respuesta que estoy buscando. Gracias. – RichardLiu