Primero haga la clase de monitor genérico. Con el poder de C++ 11 puede hacerlo tan simple como esto:
template <class F>
struct FunctionType;
template <class R, class Object, class... Args>
struct FunctionType<R (Object::*)(Args...)> {
typedef R return_type;
};
template <class R, class Object, class... Args>
struct FunctionType<R (Object::*)(Args...) const> {
typedef R return_type;
};
template <class Object_>
class Monitor {
public:
typedef Object_ object_type;
template <class F, class... Args >
typename FunctionType<F>::return_type operation(const F& f, Args... args)
{
critical_section cs;
return (object.*f)(args...);
}
template <class F, class... Args >
typename FunctionType<F>::return_type operation(const F& f, Args... args) const
{
critical_section cs;
return (object.*f)(args...);
}
private:
object_type object;
class critical_section {};
};
Por supuesto critical_section
aplicación depende de usted. Recomiendo POSIX o algunos BOOST.
Está listo para utilizar ahora:
Monitor<std::vector<int> > v;
v.operation((void (std::vector<int>::*)(const int&)) &std::vector<int>::push_back, 1);
v.operation((void (std::vector<int>::*)(const int&)) &std::vector<int>::push_back, 2);
size = v.operation(&std::vector<int>::size);
std::cout << size << std::endl;
Como se puede ver en ocasiones tendrá que indicar explícitamente qué función miembro que desea llamar - std :: vector <> tiene más de un push_back ...
para los compiladores que aún no son compatibles con la plantilla variadic - la solución sin que a continuación - tengo tiempo para un máximo de dos argumentos - que es muy incómodo - si es necesario - añadir función con más argumentos:
template <class F>
struct FunctionType;
template <class R, class Object>
struct FunctionType<R (Object::*)()> {
typedef R return_type;
};
template <class R, class Object>
struct FunctionType<R (Object::*)() const> {
typedef R return_type;
};
template <class R, class Object, class Arg1>
struct FunctionType<R (Object::*)(Arg1)> {
typedef R return_type;
};
template <class R, class Object, class Arg1>
struct FunctionType<R (Object::*)(Arg1) const> {
typedef R return_type;
};
template <class R, class Object, class Arg1, class Arg2>
struct FunctionType<R (Object::*)(Arg1,Arg2)> {
typedef R return_type;
};
template <class R, class Object, class Arg1, class Arg2>
struct FunctionType<R (Object::*)(Arg1,Arg2) const> {
typedef R return_type;
};
template <class Object_>
class Monitor {
public:
typedef Object_ object_type;
template <class F>
typename FunctionType<F>::return_type operation(const F& f)
{
critical_section cs;
return (object.*f)();
}
template <class F>
typename FunctionType<F>::return_type operation(const F& f) const
{
critical_section cs;
return (object.*f)();
}
template <class F, class Arg1>
typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1)
{
critical_section cs;
return (object.*f)(arg1);
}
template <class F, class Arg1>
typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1) const
{
critical_section cs;
return (object.*f)(arg1);
}
template <class F, class Arg1, class Arg2>
typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1, Arg2 arg2)
{
critical_section cs;
return (object.*f)(arg1, arg2);
}
template <class F, class Arg1, class Arg2>
typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1, Arg2 arg2) const
{
critical_section cs;
return (object.*f)(arg1, arg2);
}
private:
object_type object;
class critical_section {};
};
Es difícil para mí imaginar haciendo esto con menos código. El código requerido para la solución propuesta es una línea para la clase (el miembro mutex) más una línea para cada función. No creo que vaya a ser más pequeño sin un soporte de lenguaje específico. ¿Es esta tu pregunta? Si es así, la respuesta es "C++ no tiene soporte de idiomas para hacer monitores". :) –
¿Por qué no usa un mutex, está ampliamente disponible. Inventar sus propias primitivas de sincronización tiene una habilidad especial para enviar mal. –
Ver [Boost.Thread] (http://www.boost.org/libs/thread/) en caso de que no fuera lo suficientemente obvio. : -] – ildjarn